Creating and Using NestJS Custom Decorators
Learn how to create and use custom decorators in NestJS.
overview
NestJS allows you to take advantage of custom decorators to extract specific data or add specific metadata to classes and methods. Custom decorators are very useful for retrieving specific data from the request object or for simplifying things like dependency injection.
How to create a custom decorator
To create a custom decorator, first create a new decorator using the createParamDecorator
function. Below is an example of creating a custom decorator to retrieve the authenticated user’s information from the request.
Since there is a convenient CLI, we will use it to create it.
nest g d users/decorator/user
/src/users/decorators/user/user.decorator.ts
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const User = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.body.user;
},
);
The code above creates a custom decorator named User
. This decorator gets an HTTP request object from the execution context and returns its user information.
How to use custom decorators
To make use of your custom decorator, apply it to a method parameter. Below is an example that utilizes the custom decorator we created.
/src/users/users.controller.ts
import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
HttpException,
HttpStatus,
Use filters,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { ForbiddenException } from './exceptions/forbidden.exception';
import { HttpExceptionFilter } from './filters/http-exception/http-exception.filter';
import { User } from './decorator/user/user.decorator';
@Controller('users')
@UseFilters(new HttpExceptionFilter())
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
getUsers(): User[] {
return this.usersService.getUsers();
}
@Post()
addUser(@Body() name: string): void {
this.usersService.addUser(name);
}
@Put(':id')
putUser(@Param('id') id: number, @Body('name') name: string): void {
this.usersService.putUser(id, name);
}
@Delete(':id')
deleteUser(@Param('id') id: number): void {
this.usersService.deleteUser(id);
}
@Get('throw')
getException(): string {
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
@Get('custom_throw')
getCustomException(): string {
throw new ForbiddenException();
}
@Post('custom_decorator')
getCustomDecorator(@User() user: User) {
return user;
}
}
The code above uses the @User()
decorator in the getProfile
method of the ProfileController
. This will automatically extract the user information from the request and inject it into the user
parameter of the getProfile
method.
test
curl -X POST http://localhost:3000/users/custom_decorator -H 'Content-Type: application/json' -d '{"user": {"name": "test"}}'
summary
NestJS allows you to take advantage of custom decorators to extract specific data from the request object or add specific metadata to classes and methods. This allows for more flexible coding and simplified processing.