NestJS Decorators
If you’ve ever built a backend using NestJS, you’ve probably seen a lot of @Something() in the code. Those little @ symbols are decorators, and they’re one of the most powerful and elegant features of NestJS.
In this post, we’ll explore what decorators are, how they work, and go through the most common NestJS decorators used in controllers, providers, and modules.
What are Decorators?
In TypeScript, decorators are special functions that can modify classes, methods, properties, or parameters. They are a form of metadata that tells NestJS how to handle different parts of your application.
Think of them as annotations that add extra behavior to your code without having to manually write repetitive logic.
Here’s a quick example:
@Controller('users')
export class UsersController {
@Get()
findAll() {
return ['John', 'Jane', 'Alice'];
}
}
In this example:
@Controller('users')tells NestJS that this class is a controller that handles requests under the /users route.@Get()tells NestJS that findAll() responds to HTTP GET requests.
Types of NestJS Decorators
Decorators in NestJS fall into a few categories:
- Class decorators — e.g., @Controller(), @Injectable(), @Module()
- Method decorators — e.g., @Get(), @Post(), @Put(), @Delete()
- Parameter decorators — e.g., @Param(), @Body(), @Query(), @Req()
- Property decorators — e.g., @Inject()
Let’s go through them one by one.
Class Decorators
@Controller(): Used to define a controller and specify the base route path.
import { Controller, Get } from '@nestjs/common';
@Controller('products')
export class ProductsController {
@Get()
findAll() {
return ['Shoes', 'Bags', 'Hats'];
}
}
@Injectable(): Marks a class as a provider that can be injected into other classes using NestJS’s Dependency Injection system.
import { Injectable } from '@nestjs/common';
@Injectable()
export class ProductsService {
getAll() {
return ['Shoes', 'Bags', 'Hats'];
}
}
@Module(): Defines a module — the building block of every NestJS app.
import { Module } from '@nestjs/common';
import { ProductsController } from './products.controller';
import { ProductsService } from './products.service';
@Module({
controllers: [ProductsController],
providers: [ProductsService],
})
export class ProductsModule {}
Method Decorators
These decorators define routes and HTTP methods.
| Decorator | Purpose |
|---|---|
@Get() |
Handles HTTP GET requests |
@Post() |
Handles HTTP POST requests |
@Put() |
Handles HTTP PUT requests |
@Delete() |
Handles HTTP DELETE requests |
@Patch() |
Handles HTTP PATCH requests |
@All() |
Handles all HTTP request methods |
Example:
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
@Controller('users')
export class UsersController {
@Get()
findAll() {
return ['John', 'Jane'];
}
@Get(':id')
findOne(@Param('id') id: string) {
return `User #${id}`;
}
@Post()
create(@Body() userData: any) {
return { message: 'User created', user: userData };
}
}
Parameter Decorators
These extract specific parts of the request object (like body, query params, or headers).
| Decorator | Description |
|---|---|
@Param() |
Extracts a route parameter |
@Query() |
Extracts query parameters |
@Body() |
Extracts the body from a request |
@Req() |
Injects the full request object |
@Res() |
Injects the full response object |
@Headers() |
Extracts headers from a request |
@Ip() |
Extracts the client’s IP address |
Example:
import { Controller, Get, Post, Param, Body, Query, Ip } from '@nestjs/common';
@Controller('articles')
export class ArticlesController {
@Get()
findAll(@Query('category') category: string) {
return `Getting articles in category: ${category}`;
}
@Get(':id')
findOne(@Param('id') id: string) {
return `Article ID: ${id}`;
}
@Post()
create(@Body() articleData: any, @Ip() clientIp: string) {
return { message: 'Article created', clientIp, articleData };
}
}
Properly and Custom Decorators
@Inject(): Used to inject a specific provider manually (especially useful when using custom tokens).
import { Inject, Injectable } from '@nestjs/common';
@Injectable()
export class OrdersService {
constructor(@Inject('ORDERS_REPOSITORY') private ordersRepo: any) {}
}
@UseGuards(): Applies authentication or authorization guards to routes.
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from './auth.guard';
@Controller('profile')
export class ProfileController {
@UseGuards(AuthGuard)
@Get()
getProfile() {
return { name: 'John Doe', role: 'admin' };
}
}
@UseInterceptors(): Applies interceptors for transforming responses or handling logic before/after method execution.
import { Controller, Get, UseInterceptors, ClassSerializerInterceptor } from '@nestjs/common';
@Controller('users')
@UseInterceptors(ClassSerializerInterceptor)
export class UsersController {
@Get()
findAll() {
return [{ name: 'John', password: 'secret' }];
}
}
@UsePipes(): Used for validation or transformation using Pipes.
import { Controller, Post, Body, UsePipes, ValidationPipe } from '@nestjs/common';
@Controller('signup')
export class SignupController {
@Post()
@UsePipes(new ValidationPipe())
createUser(@Body() createUserDto: any) {
return { message: 'User validated and created', createUserDto };
}
}
@SetMetadata(): Attaches custom metadata to routes — often used with guards.
import { Controller, Get, SetMetadata } from '@nestjs/common';
@Controller('admin')
export class AdminController {
@SetMetadata('roles', ['admin'])
@Get()
getAdminData() {
return 'Secret admin data';
}
}
Custom Decorators
The best part is that you can even create your own decorators. For example, to extract the currently logged-in user:
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const CurrentUser = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.user;
},
);
Then use it like this:
@Get('me')
getProfile(@CurrentUser() user: any) {
return user;
}
Conclusion
Decorators are what make NestJS so elegant and developer-friendly. They remove boilerplate code and make it easy to structure your app in a modular, readable way.
For a quick recap:
- Class decorators define structure (@Controller, @Module, @Injectable)
- Method decorators define endpoints (@Get, @Post, etc.)
- Parameter decorators extract data (@Body, @Param, @Query)
- Property decorators manage injection (@Inject)
- Utility decorators control behavior (@UseGuards, @UsePipes, @UseInterceptors)
Once you get used to them, decorators will feel like second nature — turning complex backend logic into clean, declarative code.
