Composing Decorators with applyDecorators
Bundle swagger, validation, and auth decorators into a single ergonomic @ApiSecureEndpoint decorator.
The Decorator Stacking Problem
In a real NestJS enterprise API, almost every route handler ends up carrying a tall stack of decorators: Swagger docs, auth guards, role checks, and response shaping. Repeating that stack on every endpoint is verbose and error-prone.
- Duplication: the same six lines copied onto dozens of handlers.
- Drift: someone forgets
@ApiBearerAuth()on one route and the docs lie. - Noise: the actual business intent is buried under cross-cutting concerns.
This lesson teaches how to collapse a recurring decorator stack into a single reusable @ApiSecureEndpoint() using NestJS's applyDecorators.
// The pain: this stack repeats on every secured route
@Post('transfer')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth()
@ApiOperation({ summary: 'Move funds between accounts' })
@ApiOkResponse({ description: 'Transfer accepted' })
@ApiUnauthorizedResponse({ description: 'Missing or invalid token' })
async transfer(@Body() dto: TransferDto) {
return this.bank.transfer(dto);
}What applyDecorators Actually Does
applyDecorators is a helper from @nestjs/common. It takes any number of decorators and returns one new decorator that applies all of them in order when used.
- It works with method decorators, class decorators, and property decorators.
- The decorators run top-to-bottom, exactly as if you had written them by hand.
- It does not change behavior — it only composes. Whatever the original stack did, the composed decorator does identically.
Think of it as function composition for the decorator world.
import { applyDecorators, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
export function SecureRoute() {
return applyDecorators(
UseGuards(JwtAuthGuard),
ApiBearerAuth(),
ApiOperation({ summary: 'Protected route' }),
);
}All lessons in this course
- Reading Request Context with Param Decorators
- Attaching Metadata with SetMetadata and Reflector
- Composing Decorators with applyDecorators
- Class-Level Decorators for Cross-Cutting Config