Keywords: Nest.js | Query Parameters | Routing Configuration | TypeScript | API Design
Abstract: This article provides an in-depth exploration of the core differences between query parameters and path parameters in the Nest.js framework. Through practical code examples, it demonstrates how to correctly configure routes to handle query parameters and avoid common 404 errors. The content covers detailed usage scenarios of @Query() and @Param() decorators, introduces route wildcard techniques for multiple endpoint mapping, and offers complete TypeScript implementations with best practice guidelines.
Fundamental Concepts of Query Parameters and Path Parameters
In the Nest.js framework, understanding the distinction between query parameters and path parameters is crucial. Query parameters are typically used for optional operations like filtering, sorting, or pagination, while path parameters identify specific resources.
The issue in the original code stems from the route definition including a path parameter :params, which requires the URL to contain a path value. The correct approach is to remove the path parameter and use query parameters directly:
@Get('findByFilter')
async findByFilter(@Query() query): Promise<Article[]> {
// Process query logic
console.log(query); // Output: { google: '1', baidu: '2' }
}In-depth Analysis of Path Parameters
Path parameters are defined using the :paramName syntax to capture specific parts of the URL path. For example:
@Get('products/:id')
getProduct(@Param('id') id: string) {
return `Product ID: ${id}`;
}This route will match URLs like localhost:3000/products/123 and localhost:3000/products/abc, where 123 or abc are captured as the id parameter.
Route Wildcard Techniques
Nest.js supports route wildcards to map multiple endpoints to the same handler method. This is particularly useful when dealing with similar but different URL patterns:
@Get('other|te*st')
handleMultipleRoutes() {
return 'This handler matches multiple routes';
}The above configuration will match various URL patterns including localhost:3000/other, localhost:3000/test, and localhost:3000/te123st.
Complete Best Practice Example
Combining query parameters with type safety enables the creation of more robust APIs:
@Get('findByFilter')
async findByFilter(
@Query('category') category?: string,
@Query('page') page: number = 1,
@Query('limit') limit: number = 10
): Promise<Article[]> {
// Build query conditions
const whereCondition = category ? { category } : {};
// Calculate pagination
const skip = (page - 1) * limit;
return this.articleService.find({
where: whereCondition,
skip,
take: limit
});
}This implementation supports URLs like http://localhost:3000/article/findByFilter?category=tech&page=2&limit=20, providing type-safe parameter handling with sensible defaults.
Error Handling and Validation
In practical applications, parameter validation and error handling should be incorporated:
@Get('findByFilter')
async findByFilter(
@Query('page') page: number = 1,
@Query('limit') limit: number = 10
) {
// Parameter validation
if (page < 1) {
throw new BadRequestException('Page number must be greater than 0');
}
if (limit < 1 || limit > 100) {
throw new BadRequestException('Limit must be between 1 and 100');
}
// Business logic processing
return await this.getArticles(page, limit);
}Such validation mechanisms ensure API robustness and enhance user experience.