What Are Decorators?
Decorators are functions that add metadata to a class, method, or property at runtime. In NestJS, they play a crucial role in defining routes, injecting dependencies, applying guards, and more.
Built-in Decorators in NestJS
NestJS provides several built-in decorators to simplify application development:
1. Routing Decorators
@Controller(): Defines a controller for handling requests.
@Get(), @post(), @Put(), @Delete(): Define route handlers for HTTP methods.
Example:
Copy code
@Controller('users')
export class UserController {
@Get()
findAll() {
return 'This action returns all users';
}
}
- Request Object Decorators @body(): Access the request body. @Query(): Access query parameters. @param(): Access route parameters. Example:
Copy code
@Post()
createUser(@Body() createUserDto: CreateUserDto) {
return `User ${createUserDto.name} created!`;
}
3. Dependency Injection Decorators
@Injectable(): Marks a class as a provider for DI.
@Inject(): Explicitly inject a specific dependency.
Creating Custom Decorators
For advanced use cases, you can create custom decorators to encapsulate reusable logic. Here’s how:
Example: Extracting a Token
Create a custom decorator using createParamDecorator:
typescript
Copy code
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const ExtractToken = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
const authHeader = request.headers['authorization'];
if (authHeader && authHeader.startsWith('Bearer ')) {
return authHeader.slice(7);
}
return null;
},
);
Use the decorator in your controller:
@Controller('auth')
export class AuthController {
@Get('profile')
getProfile(@ExtractToken() token: string) {
return `Token: ${token}`;
}
}
Why Use Custom Decorators?
Custom decorators improve code reusability, readability, and maintainability. Instead of repeating logic across controllers, encapsulate it in a decorator for consistent and cleaner code.
Tips for Using Decorators in NestJS
Understand Execution Contexts: Decorators like createParamDecorator provide access to request objects, making them ideal for extracting and transforming data.
Leverage Metadata: Use libraries like class-validator to define validation decorators.
Combine Decorators: Use multiple decorators for complex functionalities, such as guards, interceptors, and filters.
Conclusion
Decorators in NestJS offer powerful tools for building clean, scalable applications. Whether you're using built-in decorators or creating custom ones, mastering them will take your NestJS skills to the next level.
Learn More
Official NestJS Docs: Custom Decorators
OpenAPI Integration: Swagger Decorators
import { Controller, Get, Post, Put, Delete, Param, Body } from '@nestjs/common';
// DTO for creating or updating users
class CreateUserDto {
name: string;
email: string;
}
@Controller('users') // Base route: '/users'
export class UserController {
private users = []; // Example in-memory users array for demonstration
// GET /users
@Get()
findAll() {
return this.users;
}
// GET /users/:id
@Get(':id')
findOne(@Param('id') id: string) {
const user = this.users.find(user => user.id === id);
return user || { message: `User with ID ${id} not found` };
}
// POST /users
@Post()
create(@Body() createUserDto: CreateUserDto) {
const newUser = { id: `${Date.now()}`, ...createUserDto };
this.users.push(newUser);
return { message: 'User created', user: newUser };
}
// PUT /users/:id
@Put(':id')
update(@Param('id') id: string, @Body() updateUserDto: CreateUserDto) {
const userIndex = this.users.findIndex(user => user.id === id);
if (userIndex === -1) {
return { message: `User with ID ${id} not found` };
}
this.users[userIndex] = { id, ...updateUserDto };
return { message: 'User updated', user: this.users[userIndex] };
}
// DELETE /users/:id
@Delete(':id')
delete(@Param('id') id: string) {
const userIndex = this.users.findIndex(user => user.id === id);
if (userIndex === -1) {
return { message: `User with ID ${id} not found` };
}
const deletedUser = this.users.splice(userIndex, 1);
return { message: 'User deleted', user: deletedUser };
}
}
Top comments (0)