Passa al contenuto principale

Interceptor Patterns

Cross-cutting concerns handled through NestJS interceptors.

Active Interceptors​

InterceptorPurpose
TransformInterceptorStandardize response format
ActivityLogInterceptorAudit trail for mutations
LazyTransactionInterceptorTransaction management
TimeoutInterceptorRequest timeout handling
CacheInterceptorResponse caching

TransformInterceptor​

Wraps all responses in a standard format:

@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<
T,
Response<T>
> {
intercept(
context: ExecutionContext,
next: CallHandler,
): Observable<Response<T>> {
return next.handle().pipe(
map((data) => ({
data,
statusCode: context.switchToHttp().getResponse().statusCode,
timestamp: new Date().toISOString(),
})),
);
}
}

ActivityLogInterceptor​

Records entity changes for audit:

@Injectable()
export class ActivityLogInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler) {
const request = context.switchToHttp().getRequest();
const before = this.captureState(request);

return next.handle().pipe(
tap((result) => {
this.logActivity({
action: request.method,
entity: this.getEntityName(context),
before,
after: result,
userId: request.user?.id,
});
}),
);
}
}

TimeoutInterceptor​

@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler) {
return next.handle().pipe(
timeout(30000), // 30 second timeout
catchError((err) => {
if (err instanceof TimeoutError) {
throw new RequestTimeoutException();
}
throw err;
}),
);
}
}

Applying Interceptors​

// Global
app.useGlobalInterceptors(new TransformInterceptor());

// Controller-level
@UseInterceptors(CacheInterceptor)
@Controller('employee')
export class EmployeeController {}

// Method-level
@UseInterceptors(ActivityLogInterceptor)
@Put(':id')
async update() {}