logologo
  • AI Tools

    DB Query GeneratorMock InterviewResume BuilderLearning Path GeneratorCheatsheet GeneratorAgentic Prompt GeneratorCompany ResearchCover Letter Generator
  • XpertoAI
  • MVP Ready
  • Resources

    CertificationsTopicsExpertsCollectionsArticlesQuestionsVideosJobs
logologo

Elevate Your Coding with our comprehensive articles and niche collections.

Useful Links

  • Contact Us
  • Privacy Policy
  • Terms & Conditions
  • Refund & Cancellation
  • About Us

Resources

  • Xperto-AI
  • Certifications
  • Python
  • GenAI
  • Machine Learning

Interviews

  • DSA
  • System Design
  • Design Patterns
  • Frontend System Design
  • ReactJS

Procodebase © 2024. All rights reserved.

Level Up Your Skills with Xperto-AI

A multi-AI agent platform that helps you level up your development skills and ace your interview preparation to secure your dream job.

Launch Xperto-AI

Understanding Interceptors in NestJS

author
Generated by
ProCodebase AI

10/12/2024

NestJS

Sign in to read full article

NestJS is recognized for its modular architecture and a plethora of built-in features that help developers create powerful backend applications. Among these features, interceptors stand out as a powerful tool for enhancing the functionality of your APIs. In this guide, we’ll delve deeper into what interceptors are, how they work, and some practical use cases.

What Are Interceptors?

Interceptors are a type of provider in NestJS, designed to intercept and transform incoming requests or outgoing responses. They sit between the request and the response cycle, providing a convenient way to execute custom logic, such as logging, transforming data, or managing exceptions.

Lifecycle of an Interceptor

To understand interceptors better, it's essential to grasp where they fit into the request lifecycle:

  1. Before request handling: Interceptors can manipulate a request before it reaches the handler (controller).
  2. After request handling: Interceptors can process the response once the handler processing is complete.
  3. Error handling: Interceptors can catch and handle errors before they propagate.

How to Create an Interceptor

Creating an interceptor in NestJS is straightforward. It involves a simple class implementing the NestInterceptor interface. Here’s a quick example that logs the execution time of a request:

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> { const now = Date.now(); return next .handle() .pipe( tap(() => console.log(`Request executed in ${Date.now() - now}ms`)), ); } }

Breakdown of the Example

  1. Injectable Decorator: The @Injectable() decorator is necessary, allowing Nest's dependency injection system to manage the lifecycle of the interceptor.
  2. intercept Method: This method takes an ExecutionContext and a CallHandler. The ExecutionContext provides details about the current request, such as the context of the handler being invoked.
  3. next.handle(): This method invokes the next handler in the request pipeline, returning an Observable. This is crucial in order to enable the interceptor to process the response and perform side effects using RxJS operators like tap.

Applying the Interceptor Globally

Once you’ve created an interceptor, you might want to apply it globally to affect all controllers in the application. Here’s how to do just that in your main application file:

import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { LoggingInterceptor } from './logging.interceptor'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalInterceptors(new LoggingInterceptor()); await app.listen(3000); } bootstrap();

Applying Interceptors to Specific Routes

Alternatively, if you only want to use an interceptor for specific controllers or routes, you can do so by attaching it directly in the controller:

import { Controller, Get, UseInterceptors } from '@nestjs/common'; import { LoggingInterceptor } from './logging.interceptor'; @Controller('cats') @UseInterceptors(LoggingInterceptor) export class CatsController { @Get() findAll() { // Logic to return all cats return []; } }

Real-World Use Cases

Interceptors can serve various purposes in your NestJS application. Here are some common real-world use cases:

1. Transforming Responses

You might want to consistently modify the shape of your responses. For instance, wrapping all responses in a standard format:

@Injectable() export class ResponseFormatInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { return next.handle().pipe( map(data => ({ success: true, data, })), ); } }

2. Exception Handling

Interceptors are great for handling exceptions globally. You could log the error details or return a custom response format using the following interceptor:

@Injectable() export class ExceptionInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { return next.handle().pipe( catchError(err => { console.error(err); throw new HttpException('Something went wrong', HttpStatus.INTERNAL_SERVER_ERROR); }), ); } }

3. Caching Responses

One practical application of interceptors is caching responses. Here’s a simple illustration of caching:

@Injectable() export class CachingInterceptor implements NestInterceptor { private cache = new Map(); intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const key = this.generateKey(context); if (this.cache.has(key)) { return of(this.cache.get(key)); // Return cached response } return next.handle().pipe( tap(response => this.cache.set(key, response)) // Cache the response ); } private generateKey(context: ExecutionContext): string { // Logic to generate a unique key based on context return context.switchToHttp().getRequest().url; } }

Tracking and identifying cache misses usually enhances performance and optimizes resource usage.

Conclusion

Interceptors in NestJS provide a powerful foundation for adding consistent behavior across your application. Whether it’s logging, transforming data, handling exceptions, or caching responses, they help keep your application clean and maintainable. Understanding and implementing interceptors will greatly enhance your ability to structure robust and efficient backend APIs. As you build out your NestJS projects, leverage the power of interceptors to create cleaner, more modular code!

Popular Tags

NestJSInterceptorsBackend Development

Share now!

Like & Bookmark!

Related Collections

  • NestJS Mastery: Modern Backend Development

    10/12/2024 | NestJS

Related Articles

  • Testing in NestJS using Jest

    10/12/2024 | NestJS

  • Caching in NestJS with Redis

    10/12/2024 | NestJS

  • Controllers and Routing in NestJS

    10/12/2024 | NestJS

  • Understanding Middleware in NestJS

    10/12/2024 | NestJS

  • Deployment Strategies for NestJS Applications

    10/12/2024 | NestJS

  • Understanding Guards in NestJS

    10/12/2024 | NestJS

  • WebSocket Integration in NestJS

    10/12/2024 | NestJS

Popular Category

  • Python
  • Generative AI
  • Machine Learning
  • ReactJS
  • System Design