NestJS Route Parameters
Route parameters are variable segments inside a URL. They let you pass data directly in the URL path instead of using query strings or request bodies. Route parameters appear in URLs like /users/42 or /orders/99/items/5, where 42, 99, and 5 are dynamic values your controller reads at runtime.
When to Use Route Parameters
Use route parameters to identify a specific resource. A product ID, user ID, article slug — any value that pinpoints one record in a collection belongs in the URL path.
URL Type | Use Case ----------------------------|--------------------------- GET /users/42 | Fetch one user by ID GET /posts/how-to-code | Fetch post by slug GET /orders/99/items/5 | Fetch item 5 from order 99 DELETE /files/report.pdf | Delete a file by name
Defining a Route Parameter
In NestJS, you define a route parameter by prefixing its name with a colon (:) inside the method decorator:
@Get(':id')
findOne(@Param('id') id: string) {
return `Fetching user with ID: ${id}`;
}
The :id in @Get(':id') declares the parameter. The @Param('id') decorator extracts the value from the URL and passes it into the id argument. A request to GET /users/42 delivers id = '42'.
Route Parameters Are Always Strings
NestJS extracts route parameters as strings. If your logic needs a number (like a database ID), convert it explicitly:
@Get(':id')
findOne(@Param('id') id: string) {
const numericId = parseInt(id, 10); // convert string to number
return this.usersService.findOne(numericId);
}
A shorthand using the unary + operator converts the string inline:
@Get(':id')
findOne(@Param('id') id: string) {
return this.usersService.findOne(+id); // +id converts '42' → 42
}
Extracting All Parameters at Once
When a route has several parameters, you can grab them all as an object instead of declaring each one separately:
@Get(':orderId/items/:itemId')
findItem(@Param() params: { orderId: string; itemId: string }) {
return `Order ${params.orderId}, Item ${params.itemId}`;
}
A request to GET /orders/99/items/5 delivers params = { orderId: '99', itemId: '5' }.
Nested Route Parameters Diagram
URL: /orders/99/items/5
Controller base: @Controller('orders')
Route: @Get(':orderId/items/:itemId')
orderId = '99' ← extracted from the first :orderId segment
itemId = '5' ← extracted from the second :itemId segment
Full matched path: /orders/:orderId/items/:itemId
Optional Parameters
NestJS does not support truly optional URL parameters through the standard @Param() approach. The recommended pattern is to create two separate routes — one with the parameter and one without:
@Get()
findAll() {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.usersService.findOne(+id);
}
NestJS matches routes in the order they appear. Placing @Get()` before `@Get(':id') ensures the more specific route does not accidentally catch requests meant for the general one.
Using Wildcards in Routes
NestJS supports the * wildcard to match any characters in a URL segment:
@Get('ab*cd')
matchAll() {
// Matches: /abcd, /ab-123cd, /ab-anything-cd
return 'wildcard matched';
}
Wildcards are useful for catch-all routes, but use them carefully. An overly broad wildcard can accidentally swallow requests meant for other routes.
Route Parameter Validation
NestJS does not automatically validate that :id is a number. If a user calls GET /users/not-a-number, your code receives the string 'not-a-number', and converting it with + produces NaN.
Add a ParseIntPipe to validate and convert in one step:
@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) {
// id is now guaranteed to be a number
// NestJS automatically returns 400 Bad Request if id is not a valid integer
return this.usersService.findOne(id);
}
The ParseIntPipe stops invalid requests before they reach your service and returns a 400 error automatically. Route parameters combined with pipes give you clean, safe URL handling with minimal code.
