Interceptors
Interceptors add extra logic before and after route handler execution.
Interceptors wrap the route handler execution, allowing you to run logic before and after the handler. They follow an onion/chain pattern where each interceptor wraps the next.
NestInterceptor Interface
import {
Injectable, NestInterceptor, ExecutionContext, CallHandler,
} from '@velajs/vela';
@Injectable()
class LoggingInterceptor implements NestInterceptor {
async intercept(context: ExecutionContext, next: CallHandler): Promise<unknown> {
const start = Date.now();
const result = await next.handle();
const ms = Date.now() - start;
console.log(`${context.getHandler().name} - ${ms}ms`);
return result;
}
}The CallHandler provides a single method:
| Method | Description |
|---|---|
handle() | Calls the route handler (or next interceptor) and returns Promise<unknown> with the handler's return value |
Binding Interceptors
Apply interceptors at the method or controller level with @UseInterceptors():
import { Controller, Get, UseInterceptors } from '@velajs/vela';
@Controller('spirits')
@UseInterceptors(LoggingInterceptor)
class SpiritsController {
@Get()
findAll() {
return [];
}
}Global Interceptors
Register interceptors globally so they run on every route:
const app = await VelaFactory.create(AppModule);
app.useGlobalInterceptors(new LoggingInterceptor());Or use the APP_INTERCEPTOR injection token:
import { APP_INTERCEPTOR } from '@velajs/vela';
@Module({
providers: [
{
provide: APP_INTERCEPTOR,
useClass: LoggingInterceptor,
},
],
})
class AppModule {}Response Transformation
Interceptors can modify the handler's return value before it reaches the client:
@Injectable()
class WrapResponseInterceptor implements NestInterceptor {
async intercept(context: ExecutionContext, next: CallHandler): Promise<unknown> {
const data = await next.handle();
return { data, timestamp: new Date().toISOString() };
}
}Caching Example
Short-circuit the handler by returning a cached value:
@Injectable()
class CacheInterceptor implements NestInterceptor {
private cache = new Map<string, { data: unknown; expiry: number }>();
async intercept(context: ExecutionContext, next: CallHandler): Promise<unknown> {
const request = context.getRequest();
const key = request.url;
const cached = this.cache.get(key);
if (cached && cached.expiry > Date.now()) {
return cached.data;
}
const data = await next.handle();
this.cache.set(key, { data, expiry: Date.now() + 60_000 });
return data;
}
}Pipes
Pipes transform and validate input data before it reaches the route handler.
Exception Filters
Exception filters handle errors thrown during request processing.
Last updated on