Routing determines which controller method handles a given request. This lesson covers combining controller prefixes with route decorators, path patterns, wildcards, and route ordering.
How Routes Are Defined
A route is formed by combining a controller's base path (from @Controller()) with a method's route decorator path. Nest registers these routes with the underlying HTTP adapter (Express or Fastify) in the order the classes and methods are declared.
GET /cats/breeds must be registered before GET /cats/:id, otherwise the parameterized route would match /cats/breeds first, treating "breeds" as an :id value.
Route Path Patterns
@Get() // matches exactly the controller's base path
@Get(':id') // matches a required path parameter
@Get(':id?') // matches an optional path parameter
@Get('a*z') // wildcard pattern matching
@Get('*') // catch-all within this controller
Route parameters are declared with a leading colon, like :id.
Wildcards (*) match any characters in that path segment.
More specific literal routes should be registered before similarly-shaped parameterized routes.
A controller-level prefix combines with each method's path to form the full route.
Routing Cheatsheet
Route decorators and patterns used throughout NestJS controllers.
Pattern
Example
Matches
Base route
@Get()
GET /cats
Subpath
@Get('active')
GET /cats/active
Parameter
@Get(':id')
GET /cats/42
Multiple parameters
@Get(':id/owners/:ownerId')
GET /cats/42/owners/7
Any method
@All()
Any HTTP verb on this route
Redirect
@Redirect(url, code)
Sends an HTTP redirect response
Route Prefixes and Global Prefixes
Beyond per-controller prefixes, you can set a global prefix for the entire application (e.g. /api) using app.setGlobalPrefix() in main.ts, useful when the API and a separate frontend share the same domain.
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('api');
await app.listen(3000);
// GET /cats becomes GET /api/cats
Route Ordering Caveats
Just like Express, NestJS matches routes in the order they are registered, which for controllers means the order of methods within a class, and the order controllers are listed within a module.
Common Mistakes
Registering a parameterized route before a literal one that could otherwise be shadowed.
Forgetting a leading colon on a route parameter, writing @Get('id') instead of @Get(':id').
Assuming a global prefix applies retroactively to already-hardcoded absolute URLs in client code.
Overusing wildcard routes when a couple of explicit routes would be clearer.
Key Takeaways
A full route is the controller's base path combined with the method's route decorator path.
Route parameters use a leading colon, and can be optional with a trailing ?.
Literal routes should be registered before conflicting parameterized routes.
app.setGlobalPrefix() adds a prefix to every route in the application.
Pro Tip
When a controller has both a literal subpath and a parameterized one that could collide (like /cats/featured and /cats/:id), add a short comment above the literal route explaining why its ordering matters, future edits are the most common way this kind of bug gets reintroduced.
You now understand NestJS routing. Next, learn how to access the raw Request Object inside a route handler.