In NestJS, decorators are typically used for declaratively adding metadata, creating parameter decorators, and defining dependency injection behavior, rather than directly executing database requests. However, custom decorators can be created to influence logic related to database operations, such as retrieving the current request's user and using this information for database queries.
For example, suppose we need to retrieve the authenticated user across multiple controller methods and potentially use this user information to fetch additional details from the database. We can create a custom decorator to accomplish this task:
First, create a decorator in CurrentUser.ts:
typescriptimport { createParamDecorator, ExecutionContext } from '@nestjs/common'; import { User } from './user.entity'; // Create a custom parameter decorator export const CurrentUser = createParamDecorator( async (data: unknown, context: ExecutionContext): Promise<User> => { const request = context.switchToHttp().getRequest(); const user = request.user; // Assuming `request.user` has been set by a previous middleware or guard (e.g., Passport) // Here, database operations can be performed, such as querying user details using the user ID // const userRepository = ... // Get your Repository instance // const userDetails = await userRepository.findOne(user.id); // Return user information (or specific user details) // return userDetails; return user; }, );
Next, use this decorator in the controller:
typescriptimport { Controller, Get } from '@nestjs/common'; import { CurrentUser } from './decorators/current-user.decorator'; import { User } from './user.entity'; @Controller('profile') export class ProfileController { @Get() async getProfile(@CurrentUser() user: User) { // Here, `user` will be the user entity provided by the `CurrentUser` decorator // You can use this entity to perform database operations, such as fetching detailed user information return user; } }
In the above example, the CurrentUser decorator encapsulates the logic for retrieving user information from the request object, assuming that request.user has been set by a previous middleware or guard (e.g., Passport). In practice, you can perform more complex database queries as needed and return the results to the controller.
It's important to note that directly executing database operations or other complex logic within decorators may lead to challenging maintenance and testing. Therefore, it's generally recommended to handle such logic in the service layer, with decorators only performing simple mapping or metadata extraction. If database queries are indeed needed within decorators, ensure the logic is clear and consider the impact on performance and error handling.