0
0
NestJSframework~5 mins

Why interceptors add cross-cutting logic in NestJS

Choose your learning style9 modes available
Introduction

Interceptors let you add extra steps that run before or after your main code. This helps you handle common tasks in one place, so you don't repeat code everywhere.

Logging every request and response in your app
Measuring how long a function takes to run
Modifying data before sending it back to the user
Handling errors in a consistent way across many parts
Adding security checks before running certain code
Syntax
NestJS
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before handler');
    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After handler... ${Date.now() - now}ms`)),
      );
  }
}

The intercept method runs before and after the main handler.

You must return next.handle() to continue the request flow.

Examples
Simple interceptor that logs before the handler runs.
NestJS
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
  console.log('Start');
  return next.handle();
}
Interceptor that logs after the handler finishes.
NestJS
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
  return next.handle().pipe(
    tap(() => console.log('After handler')),
  );
}
Interceptor measuring how long the handler takes.
NestJS
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
  const start = Date.now();
  return next.handle().pipe(
    tap(() => console.log(`Took ${Date.now() - start}ms`)),
  );
}
Sample Program

This example shows a controller with a TimerInterceptor. The interceptor logs how long the request took. When you call the /hello route, it returns 'Hello, world!' and logs the time.

NestJS
import { Controller, Get, UseInterceptors, Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
class TimerInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const start = Date.now();
    return next.handle().pipe(
      tap(() => console.log(`Request took ${Date.now() - start}ms`)),
    );
  }
}

@Controller('hello')
@UseInterceptors(TimerInterceptor)
export class HelloController {
  @Get()
  sayHello(): string {
    return 'Hello, world!';
  }
}
OutputSuccess
Important Notes

Interceptors work like a sandwich: code before and after your main logic.

They help keep your code clean by handling common tasks in one place.

Remember to always call next.handle() to continue the flow.

Summary

Interceptors add shared logic before and after your main code.

They are great for logging, timing, error handling, and more.

Using interceptors keeps your app organized and easier to maintain.