Migrating to Nile
Type: Guide
This document provides a step-by-step process for migrating an existing REST API to Nile. The migration is a restructuring exercise, not a rewrite.
1. Prerequisites
- Your existing backend separates business logic from the routing layer
- You have a working understanding of Nile's service-action model
- You can run both the old and new servers side by side during migration
If your business logic is tightly coupled to your routing layer, extract it first. This is a standard refactoring step that most production backends have already done.
2. Migration Strategy
Migrate one service at a time. Do not rewrite the entire backend at once. Run the old and new servers in parallel, routing traffic gradually.
3. Step One: Map Existing Endpoints to Services and Actions
List all existing endpoints and group them by domain:
Each row becomes one Nile action. The service groups related actions.
4. Step Two: Extract Business Logic into Action Handlers
For each endpoint, move the handler logic into a Nile action. The business logic does not change. Only the wrapper changes.
Before (Express-style)
After (Nile)
The business logic (createUser) is unchanged. The wrapper changes from Express route handler to Nile action handler. The error handling changes from res.status(400) to Err(). Validation moves from manual checks to Zod.
5. Step Three: Adopt the Result Pattern
Replace throw and res.status() with Ok() and Err(). This is the most significant code change in the migration.
Before
After
The logic is identical. The error signaling changes from HTTP status codes to Err() returns. Nile maps these to consistent HTTP responses automatically.
6. Step Four: Replace Middleware with Hooks
Global middleware becomes global hooks. Per-route middleware becomes action hooks.
Before (Express middleware)
After (Nile hooks)
Authentication is configured once at the server level. Cross-cutting concerns like logging go in onBeforeActionHandler. Per-action pre-processing uses the hooks.before array on individual actions.
7. Step Five: Update the Client
Replace endpoint-specific client calls with Nile client invocations.
Before
After
The response shape changes from whatever your old API returned to { status, message, data }. Update your frontend to handle this format.
8. Step Six: Migrate Incrementally
Run both servers during the transition. Route traffic one service at a time:
- Migrate the
usersservice. Point/api/userstraffic to Nile. - Verify all user operations work correctly.
- Migrate the
ordersservice. Point/api/orderstraffic to Nile. - Repeat for each service.
- Remove the old server once all services are migrated.
Use a reverse proxy or API gateway to route traffic based on the service path. This allows rollback at any step.
9. What Does Not Change
- Database layer: Your models, queries, and migrations remain unchanged.
- Business logic: The core logic inside your handlers is copied, not rewritten.
- External integrations: Third-party API calls, email services, payment gateways work the same way.
- Testing strategy: Unit tests for business logic remain valid. Only integration tests need updating.
10. Common Pitfalls
- Do not rewrite business logic: Copy it into action handlers. Refactor later if needed.
- Do not migrate everything at once: One service at a time. Verify each before moving to the next.
- Do not skip validation: Replace manual validation with Zod schemas. This is where Nile adds value.
- Do not ignore the Result pattern:
Ok()andErr()are not optional. They are the framework contract.