Careeroza
Route Parameters and Query
@Param and @Query
@Param('id') reads a path segment. @Query('name') reads a query string value. Both are strings unless a pipe converts them.
import { Controller, DefaultValuePipe, Get, Param, ParseIntPipe, Query } from '@nestjs/common';
@Controller('products')
export class ProductsController {
// GET /products?category=audio&page=2
@Get()
findAll(
@Query('category') category: string | undefined,
@Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
) {
return { category: category ?? 'all', page };
}
// GET /products/7
@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) {
return { id, typeOfId: typeof id };
}
}Requests and Responses
Example
curl "http://localhost:3000/products?category=audio&page=2"
curl http://localhost:3000/products
curl http://localhost:3000/products/7
curl -i http://localhost:3000/products/abcExample output
{"category":"audio","page":2}
{"category":"all","page":1}
{"id":7,"typeOfId":"number"}
HTTP/1.1 400 Bad Request
{"message":"Validation failed (numeric string is expected)","error":"Bad Request","statusCode":400}How Path Matching Works
Example
Underneath, the router compares the pattern /products/:id with the URL segment by segment. A tiny version:
function match(pattern: string, url: string): Record<string, string> | null {
const [path, qs = ''] = url.split('?');
const want = pattern.split('/');
const got = path.split('/');
if (want.length !== got.length) return null;
const params: Record<string, string> = {};
for (let i = 0; i < want.length; i++) {
if (want[i].startsWith(':')) params[want[i].slice(1)] = decodeURIComponent(got[i]);
else if (want[i] !== got[i]) return null;
}
for (const pair of qs.split('&').filter(Boolean)) {
const [k, v] = pair.split('=');
params['query.' + k] = v;
}
return params;
}
console.log(match('/products/:id', '/products/7'));
console.log(match('/orders/:orderId/items/:itemId', '/orders/42/items/3?expand=product'));
console.log(match('/products/:id', '/users/7'));Output
{ id: '7' }
{ orderId: '42', itemId: '3', 'query.expand': 'product' }
null