Introduction
When building web applications, ensuring smooth communication between the client and the server is important. HTTP interceptors help streamline this communication. Using HTTP interceptors, you can catch and modify HTTP requests and responses before they reach your application. You can control your requests by adding authentication tokens, logging, dealing with errors, and changing data all in one place. In this blog, we’ll explore how to implement HTTP interceptors in three popular JavaScript frameworks: React, Angular, and Next.js. By the end of this blog, you’ll know how to implement HTTP interceptors in these frameworks and apply best practices in your projects. Let’s get started!
React
HTTP interceptors in React are commonly implemented using Axios, a popular HTTP client. Axios provides a simple way to intercept requests and responses, making it easy to handle tasks such as authentication, logging, and error handling.
Setup the project
Before developing a interceptor in your React project first make sure you have the following:
- Node.js and npm/yarn Installed: Ensure you have latest version of Node.js and npm (or yarn) installed on your machine. You can download Node.js from here.
- A React Project Setup: Now you have to setup a React project. You can create a new React project using vite which is a faster alternative to create-react-app package:
npm create vite@latest my-axios-app --template react
cd my-axios-app
Install Axios: Now we have to install axios to our React project. You can install Axios using npm or yarn:
npm install axios
or
yarn instal axios
Implementing Request Interceptors in React
Request interceptors allow you to modify requests before they are sent to the server. This can be useful for adding authentication tokens, setting custom headers, or logging requests. Let’s see how to implement request interceptors in a React application using Axios.
Step 1: Create an Axios Instance
Start by creating a new file axiosInstance.js
, Here you will create a Axios instance in which you can add a request interceptor to intercept all the request send by the application. This interceptor will be executed before every request is sent out.
Creating an Axios instance allows you to set default configurations, such as the base URL and headers, that will be applied to all requests made with that instance. This helps in keeping your code DRY (Don’t Repeat Yourself)
import axios from 'axios';
const axiosInstance = axios.create({
baseURL: 'https://dummyjson.com', // Replace with your API base URL
timeout: 1000,
headers: { 'Content-Type': 'application/json' }
}); // Create the axios instance
// Add a request interceptor
axiosInstance.interceptors.request.use(
function (config) {
// Do something before the request is sent
// For example, add an authentication token to the headers
const token = localStorage.getItem('authToken'); // taking auth token from local Storage
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
function (error) {
// Handle the error
return Promise.reject(error);
}
);
Here’s a summary of what we’ve done:
- Created an Axios instance using axios.create().
- Set the
baseURL
to the base URL of your API. You can adjust this to match your API’s configuration. - Used interceptors.request.use() to intercept and modify outgoing requests. This allows us to add headers, authentication tokens, or make other changes to the request configuration.
Step 2: Use the Axios Instance in React Components
With the request interceptor set up, we can use the Axios instance in your React components. The interceptor will automatically catch all the requests and add the token (or perform any other configured actions) before it is sent.
// src/App.js
import React, { useEffect, useState } from 'react';
import axiosInstance from './axiosInstance';
function App() {
const [data, setData] = useState(null);
useEffect(() => {
axiosInstance.get('/products/1') // Replace with your API endpoint
.then(response => {
setData(response.data);
})
.catch(error => {
console.error('Error fetching data:', error);
});
}, []);
return (
Data from API
{data ? (
{JSON.stringify(data, null)}
) : (Loading...
)} );
} export default App;
As you can see In this example, the request to the API endpoint will include the authorization token in the headers, thanks to the request interceptor.
Angular
Angular provides a native way to easily create HTTP Interceptors, which let you catch and handle requests and responses centrally. In this guide, we will see how to create an Angular HTTP Interceptor to manage tasks like adding headers, logging requests, or handling errors in one place.
Step 1: Setting Up Your Angular Project
Lets start by first, making sure we have Angular CLI installed. If not, you can install it with npm:
npm install -g @angular/cli
Now, create a new Angular project:
ng new Project_Name
cd Project_Name
Step 2: Generating the Interceptor
Generate a new HTTP Interceptor with Angular CLI:
ng generate interceptor interceptors/interceptorName
This will create two files: interceptorName.interceptor.ts
and interceptorName.interceptor.spec.ts
in the src/app/interceptors
directory.
Step 3: Implementing the Interceptor
Open interceptorName.interceptor.ts
and add the logic for your interceptor. Here’s an example that logs a message.
import { HttpInterceptorFn } from '@angular/common/http';
export const interceptorName: HttpInterceptorFn = (req, next) => {
console.log('HTTP Request:', req);
return next(req);
};
Step 4: Registering the Interceptor
To use the interceptor, open app.config.ts
and add it to the providers array:
import { provideHttpClient,withInterceptors } from '@angular/common/http';
import { interceptorName } from './interceptors/interceptorName.interceptor';
export const appConfig: ApplicationConfig = {
providers: [
....
provideHttpClient(
withInterceptors([interceptorName])
),
],
};
Step 5: Testing the Interceptor
Now, let’s test the interceptor. Create a service to make HTTP requests and see if the interceptor adds the log .
ng generate service services/test
Add a basic GET request in test.service.ts:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class TestService {
private apiUrl ='API_URL'
constructor(private http: HttpClient) { }
getTestData(): Observable {
return this.http.get(this.apiUrl);
}
}
Update app.component.ts to use this service and log the response:
import { Component } from '@angular/core';
import { TestService } from './service/test.service';
import { Observable } from 'rxjs';
@Component({
...
template:`
UserID: {{ data.userId }}
Title: {{ data.title }}
`,
})
export class AppComponent {
...
data$!: Observable;
constructor(private testService: TestService) { }
ngOnInit(): void {
this.data$ = this.testService.getTestData()
}
}
Step 6: Running the Application
Finally, run your Angular app to see the interceptor in action:
ng serve
Open your browser and go to http://localhost:4200. You should see the API response in the console.
NestJS
Interceptors in NestJS are implemented by creating classes that implement the NestInterceptor
interface. These classes define custom logic that runs before or after the execution of route handlers.
Step 1: Set Up Your NestJS Project
First, ensure you have NestJS CLI installed. If not, you can install it globally using:
npm install -g @nestjs/cli
Create a new NestJS project:
nest new my-nestjs-app
cd my-nestjs-app
Step 2: Create the Interceptor
Generate a new interceptor using the NestJS CLI:
nest generate interceptor common/logging
This will create a new interceptor in the src/common/logging directory. Open the generated logging.interceptor.ts file and update it as follows:
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 {
console.log('Before...');
const now = Date.now();
return next
.handle()
.pipe(tap(() => console.log(`After... ${Date.now() - now}ms`)));
}
}
This simple interceptor logs messages before and after the request is handled.
Step 3: Apply the Interceptor Globally
To apply the interceptor globally, update your app.module.ts
file:
import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { LoggingInterceptor } from './common/logging/logging.interceptor';
@Module({
imports: [],
controllers: [AppController],
providers: [
AppService,
{
provide: APP_INTERCEPTOR,
useClass: LoggingInterceptor,
},
],
})
export class AppModule {}
Step 4: Test Your Interceptor
Run your NestJS application:
npm run start
Access your endpoint at http://localhost:3000/ and observe the console logs. You should see the logs from the interceptor before and after the request is handled.
Framework-Independent Alternative: Using Requestly
While Axios has powerful tools for processing HTTP requests within applications, integrating and managing interceptors directly within your codebase can be difficult and demand changes to your application’s architecture. Instead of depending on framework-specific solutions such as Axios interceptors, developers can use Requestly, a browser extension that modifies network requests and responses without requiring any changes to the application’s code. This method has various advantages over standard interceptors:
Simplifying Modifications with Requestly
- No Code Changes Required: Unlike implementing interceptors in your application code, which requires understanding and modifying the codebase, Requestly operates entirely from the browser. This means developers can modify requests and responses dynamically without touching the application’s source code.
- Flexibility Across Technologies: Requestly’s framework-independent nature allows it to work seamlessly across different projects and technologies. Whether you’re working with React, Angular, Vue.js, or any other framework, Requestly provides a consistent interface for managing network traffic.
Advantages of Using Requestly
- Ease of Use: Requestly simplifies the process of modifying network requests and responses through an intuitive browser extension interface. This accessibility makes it ideal for developers of all skill levels, from beginners to advanced users.
- Immediate Testing and Debugging: With Requestly, developers can instantly test and debug different scenarios by altering headers, URLs, or response content. This capability speeds up development cycles and enhances troubleshooting efficiency.
- Enhanced Privacy and Security: Requestly empowers developers to block or modify requests to enhance privacy, security, and compliance with data protection regulations. For instance, blocking tracking scripts or adding secure headers can be done effortlessly.
Example Use Cases
- Modify Server Response: Modify response content to simulate various server behaviors without backend changes.
- Testing Different API Requests: Dynamically alter request to test different API endpoints or data payloads.
- **Blocking Network Request :** Test your website under scenarios where certain external resources are unavailable
- Adding Custom Headers : Add authentication tokens or custom CORS headers for testing APIs that require specific headers.
How to use Requestly Interceptor
Modify API Response
Requestly allows you to modify API responses. It provides a user-friendly interface for overriding the response body of API requests, allowing you to mimic different data scenarios that your frontend might encounter.
Insert/Inject Script
Insert/Inject Script Rule allows you to inject JavaScript and CSS into web pages as they load. This means you can modify the DOM, change styles, or even add new functionality without altering the source code directly. It’s important for testing hypotheses or debugging during the development and quality assurance process. Learn more about it here.
Replace Rule
Replace Rule enables you to replace a String in URL with another String. This feature is particularly useful for developers to swap the API endpoints from one environment to another or change something specific in the URL. Requests are matched with source condition, and find and replace
are performed on those requests by redirecting to the resulting URL. Learn more about this rule here.
Conclusion
In this blog post, we’ve explored the powerful concept of Intercepting requests with Axios in React which allows us developers to have more control over our HTTP requests and responses within their applications, Whether it’s adding authentication tokens, logging requests for debugging purposes, or handling errors globally, Axios interceptors provide a flexible solution to meet diverse development needs.