Query Parameters
⭐ Interview Importance: LOW
⏱️ Revision Time: 14 min
Query parameters are used to pass optional filtering, sorting, or pagination data in the URL.
Overview
Unlike Route Parameters (which are part of the path, e.g., /users/1), Query Parameters are appended to the end of the URL after a question mark (e.g., /users?limit=10&page=2).
In NestJS, you extract query string parameters using the @Query() decorator.
Key Concepts
@Query(key?: string): Extracts the query parameter matching the given key. If no key is provided, it extracts the entire query object.- String Types: Just like route parameters, all query parameters are initially strings (or arrays of strings).
- Validation and Transformation: You can use DTOs (Data Transfer Objects) and
ValidationPipeto automatically transform and validate query strings.
Code Examples
Extracting Specific Query Parameters
import { Controller, Get, Query } from '@nestjs/common';
@Controller('products')
export class ProductsController {
// GET /products?limit=20&sort=asc
@Get()
findAll(
@Query('limit') limit: string,
@Query('sort') sort: string,
) {
return `Fetching ${limit} products sorted by ${sort}`;
}
}
Type Transformation
Because query params are strings, you should use Pipes to convert them if you need numbers or booleans.
import { ParseIntPipe, ParseBoolPipe, DefaultValuePipe } from '@nestjs/common';
@Get()
findAll(
// Use DefaultValuePipe so it doesn't throw if the user omits the query param
@Query('limit', new DefaultValuePipe(10), ParseIntPipe) limit: number,
@Query('active', new DefaultValuePipe(true), ParseBoolPipe) active: boolean,
) {
// 'limit' is a number, 'active' is a boolean
return this.productsService.findAll(limit, active);
}
Using DTOs for Complex Queries (Recommended)
When you have multiple query parameters (pagination, filtering, sorting), it is much cleaner to use a DTO class with class-validator and class-transformer.
// pagination.dto.ts
import { IsInt, IsOptional, Min } from 'class-validator';
import { Type } from 'class-transformer';
export class PaginationQueryDto {
@IsOptional()
@Type(() => Number) // Transforms the string to a number!
@IsInt()
@Min(1)
limit?: number = 10; // Default value
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
page?: number = 1;
}
// products.controller.ts
@Get()
findAll(@Query() query: PaginationQueryDto) {
// query is now a fully typed and validated object
return this.productsService.findAll(query.limit, query.page);
}
Note: To make @Type(() => Number) work automatically, ensure transform: true is set in your global ValidationPipe.
Best Practices
- Use DTOs for Pagination/Filtering: If a route accepts more than two query parameters, always use a DTO. It keeps your controller signature clean and centralizes validation rules.
- Enable
transform: true: When setting up your globalValidationPipeinmain.ts, pass{ transform: true }. This enables theclass-transformerlibrary to automatically convert query string values into the correct types based on your DTO class definitions.