Mastering HTTP Interceptors in Angular

Mastering HTTP Interceptors in Angular

In modern web development, handling HTTP requests and responses efficiently is crucial for creating a seamless user experience. Angular provides a powerful feature called HTTP Interceptors that allows you to intercept and manipulate HTTP requests and responses before they reach the backend or the frontend application.

This article will guide you through the concept of HTTP Interceptors in Angular, showcasing how they can be used for tasks such as adding authentication tokens, modifying headers, logging requests, handling errors, and more.

What are HTTP Interceptors in Angular?

HTTP Interceptors in Angular are part of the HttpClientModule and allow you to intercept HTTP requests and responses. Interceptors are services that can be used to:

  • Modify the request before it’s sent to the server.
  • Transform or modify the response before passing it to the subscriber.
  • Handle or log errors that occur during the request-response cycle.

They are implemented by creating a service that implements the HttpInterceptor interface, which provides methods to manipulate requests and responses.

How HTTP Interceptors Work in Angular

HTTP interceptors are chainable, meaning multiple interceptors can be used in sequence. When a request is made, the request passes through all active interceptors before it reaches the backend API. Similarly, when the response is returned, it passes through each interceptor before it is handed to the component.

An HttpInterceptor needs to implement the intercept() method, which accepts two parameters: the HttpRequest and HttpHandler. It’s the job of the intercept() method to modify the request or handle the response.

Creating an HTTP Interceptor in Angular

Let’s walk through the steps to create a simple HTTP Interceptor in Angular:

1. Set Up Angular Project

Ensure you have an Angular project set up with the HttpClientModule imported. If you don't have this set up yet, do so by running:

ng new angular-http-interceptor
cd angular-http-interceptor
ng add @angular/common/http

2. Create the Interceptor Service

Create an interceptor service by running:

ng generate service interceptors/auth

Now, open the generated auth.interceptor.ts file and implement the HttpInterceptor interface:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // Clone the request and add the authorization header
    const clonedRequest = req.clone({
      setHeaders: {
        Authorization: `Bearer your-token-here`
      }
    });

    // Pass the cloned request to the next handler in the chain
    return next.handle(clonedRequest);
  }
}

In this example, we are adding an Authorization header to every HTTP request. You can modify this logic to suit your needs, such as adding custom headers, logging requests, or modifying request body content.

3. Provide the Interceptor in App Module

After creating the interceptor, you need to register it in the AppModule so Angular knows to use it. Open app.module.ts and add the interceptor in the providers array:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { AuthInterceptor } from './interceptors/auth.interceptor';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, HttpClientModule],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

By setting multi: true, you ensure that Angular allows multiple interceptors to be used.

Common Use Cases for HTTP Interceptors

Adding Authentication Tokens: One of the most common use cases for an HTTP interceptor is adding an authentication token to requests. This ensures that the user is authorized to access protected resources.
const clonedRequest = req.clone({
  setHeaders: {
    Authorization: `Bearer ${this.authService.getToken()}`
  }
});

Handling Errors Globally: HTTP interceptors can be used to catch and handle errors across the entire application. For example, you can handle authentication failures or server errors globally instead of in each individual HTTP request.
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  return next.handle(req).pipe(
    catchError(error => {
      if (error.status === 401) {
        this.authService.logout();
      }
      return throwError(error);
    })
  );
}

Logging HTTP Requests and Responses: Another common use case is to log all HTTP requests and responses. This can be useful for debugging and monitoring.
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  console.log('Request:', req);
  return next.handle(req).pipe(
    tap(event => {
      if (event instanceof HttpResponse) {
        console.log('Response:', event);
      }
    })
  );
}

Modifying HTTP Headers: HTTP interceptors can be used to add or modify headers, such as setting a Content-Type or adding custom headers based on certain conditions.
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  const clonedRequest = req.clone({
    setHeaders: {
      'X-Custom-Header': 'customValue'
    }
  });
  return next.handle(clonedRequest);
}

Best Practices for Using HTTP Interceptors

  • Use for Cross-Cutting Concerns: HTTP interceptors are perfect for tasks that should be handled globally, such as logging, caching, authentication, and error handling.
  • Chain Multiple Interceptors: You can chain multiple interceptors to handle different concerns. Angular will execute them in the order they are registered in the providers array.
  • Avoid Modifying Response Directly: While it's possible to modify the response, it is generally better to use interceptors to modify the request and handle errors, not to transform the actual response data. For that, services or components are better suited.

Conclusion

HTTP interceptors in Angular provide a powerful way to handle and manipulate HTTP requests and responses globally. They allow for tasks like adding authentication headers, logging HTTP traffic, managing errors, and more. Interceptors help improve the maintainability and scalability of your application by centralizing cross-cutting concerns.

By incorporating interceptors into your Angular application, you can streamline request and response handling, improve security, and ensure a more robust user experience across all HTTP interactions.


Post a Comment

Previous Post Next Post