How to Use @UseInterceptors in NestJS: Simple Guide
In NestJS, use
@UseInterceptors to apply interceptors that can transform or extend request handling. Attach it to controllers or methods by passing the interceptor class inside the decorator to modify behavior like logging, caching, or response mapping.Syntax
The @UseInterceptors decorator takes one or more interceptor classes as arguments. You place it above a controller method or an entire controller class to apply the interceptor(s).
- @UseInterceptors(InterceptorClass): Applies the interceptor to the target.
- InterceptorClass must implement the
NestInterceptorinterface.
typescript
import { UseInterceptors } from '@nestjs/common'; @UseInterceptors(InterceptorClass) class SomeController { @UseInterceptors(AnotherInterceptor) someMethod() { // method logic } }
Example
This example shows a simple logging interceptor applied to a controller method. The interceptor logs before and after the method runs.
typescript
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, Controller, Get, UseInterceptors } from '@nestjs/common'; import { Observable, tap } from 'rxjs'; @Injectable() class LoggingInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { console.log('Before handler execution'); const now = Date.now(); return next.handle().pipe( tap(() => console.log(`After handler execution: ${Date.now() - now}ms`)), ); } } @Controller('test') class TestController { @Get() @UseInterceptors(LoggingInterceptor) getHello() { return 'Hello World'; } }
Output
Console output when GET /test is called:
Before handler execution
After handler execution: Xms
Response to client:
"Hello World"
Common Pitfalls
- Not implementing
NestInterceptorinterface in your interceptor class causes errors. - Forgetting to return
next.handle()insideinterceptmethod breaks the request flow. - Applying
@UseInterceptorswithout importing it from@nestjs/commonleads to runtime errors. - Using interceptors globally requires
app.useGlobalInterceptors()instead of@UseInterceptors.
typescript
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable } from 'rxjs'; // Wrong interceptor: missing next.handle() return @Injectable() class WrongInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { console.log('Intercepted'); // Missing return next.handle() breaks flow return; // Added to avoid syntax error but this is incorrect usage } } // Correct interceptor @Injectable() class CorrectInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { console.log('Intercepted'); return next.handle(); } }
Quick Reference
@UseInterceptors decorator usage summary:
| Usage | Description |
|---|---|
| @UseInterceptors(MyInterceptor) | Apply interceptor to a method or controller |
| Interceptor class | Must implement NestInterceptor interface |
| Global interceptors | Use app.useGlobalInterceptors() instead |
| Usage | Description |
|---|---|
| @UseInterceptors(MyInterceptor) | Apply interceptor to a method or controller |
| Interceptor class | Must implement NestInterceptor interface |
| Global interceptors | Use app.useGlobalInterceptors() instead |
Key Takeaways
Use @UseInterceptors to apply interceptors on controllers or methods in NestJS.
Interceptor classes must implement the NestInterceptor interface and return next.handle().
Apply interceptors globally with app.useGlobalInterceptors(), not @UseInterceptors.
Always import @UseInterceptors from @nestjs/common to avoid errors.
Interceptors can modify or log requests and responses by wrapping handler execution.