Custom Decorators
Custom Decorators
You have used many decorators — @Get(), @Body(), @UseGuards(). NestJS lets you build your own, making controllers cleaner and intent clearer. This lesson covers parameter decorators, metadata decorators, and combining them — and ties together the whole request lifecycle.
Custom parameter decorators
Reaching into the request for the same value in every handler is repetitive. A custom parameter decorator extracts it once, declaratively. The classic example is a @User() decorator that pulls the authenticated user off the request:
Now any handler reads the user with a clean, self-describing parameter:
data argument is whatever you pass into the decorator — @User('email') passes 'email' as data. This lets one decorator return either the whole object or a single field.
Metadata decorators
You met @SetMetadata() with guards. Wrapping it in a named decorator makes intent obvious and avoids magic strings scattered around the code:
The matching guard reads it back with reflector.get('roles', context.getHandler()), exactly as in the guards lesson.
Composing decorators
applyDecorators() bundles several decorators into one reusable decorator — great for a common combination like "requires auth + a role + Swagger docs":
The full request lifecycle
Now that you have met every building block, here is the order each request flows through:
Summary
Custom decorators make controllers expressive: createParamDecorator extracts request data (like @User()), SetMetadata wrappers (like @Roles()) attach metadata for guards, and applyDecorators composes several into one. With the full lifecycle — middleware, guards, interceptors, pipes, handler, filters — now clear, you have completed Phase 3 and can build robust, well-structured NestJS request handling.