Angular HTTP Interceptor for Request Transformation
Angular's HTTP interceptors are powerful tools that allow you to intercept and modify outgoing HTTP requests and incoming HTTP responses. This challenge will test your ability to create a custom interceptor that modifies outgoing requests by adding a custom header. This is a common requirement for tasks like authentication, logging, or injecting global configurations.
Problem Description
Your task is to create an Angular HTTP interceptor that adds a specific custom header to all outgoing HTTP requests made through Angular's HttpClient.
Key Requirements:
- Create an
HttpInterceptorclass: This class must implement theHttpInterceptorinterface from@angular/common/http. - Intercept outgoing requests: The interceptor should modify outgoing
HttpRequestobjects. - Add a custom header: For every outgoing request, add a header named
X-Custom-App-Versionwith the value1.0.0. - Provide the interceptor to Angular: Ensure the interceptor is registered correctly in your Angular application's module.
- Test the interceptor: Demonstrate that the interceptor successfully adds the header to requests.
Expected Behavior:
When an HTTP request is made using HttpClient in your Angular application, the X-Custom-App-Version: 1.0.0 header should be present in the outgoing request.
Edge Cases to Consider:
- Requests that might already have an
X-Custom-App-Versionheader (though for this challenge, we'll assume it's not present beforehand or can be overwritten). - Handling different types of HTTP methods (GET, POST, PUT, DELETE, etc.).
Examples
Let's imagine a simple Angular service that makes an HTTP request:
Example 1: Basic GET Request
Input (Conceptual - How the request is initiated in a service):
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
private apiUrl = 'https://api.example.com/items';
constructor(private http: HttpClient) { }
getItems(): Observable<any[]> {
return this.http.get<any[]>(this.apiUrl);
}
}
Output (Conceptual - What the actual network request looks like):
GET https://api.example.com/items HTTP/1.1
Host: api.example.com
... (other default headers)
X-Custom-App-Version: 1.0.0
Explanation:
The DataService's getItems method makes a GET request. The interceptor intervenes, adds the X-Custom-App-Version header, and the modified request is sent to the server.
Example 2: POST Request with Body
Input (Conceptual - How the request is initiated in a service):
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DataService {
private apiUrl = 'https://api.example.com/items';
constructor(private http: HttpClient) { }
createItem(item: any): Observable<any> {
return this.http.post<any>(this.apiUrl, item);
}
}
Output (Conceptual - What the actual network request looks like):
POST https://api.example.com/items HTTP/1.1
Host: api.example.com
Content-Type: application/json
... (other default headers)
X-Custom-App-Version: 1.0.0
{ "name": "New Item", "value": 123 }
Explanation:
Similar to the GET request, the POST request also gets the custom header added by the interceptor. The request body remains untouched.
Constraints
- The interceptor must be implemented in TypeScript.
- You should use Angular's standard
HttpClientandHttpInterceptormechanisms. - The header value
1.0.0is fixed for this challenge. - The header name
X-Custom-App-Versionis fixed. - The interceptor should be registered as a multi-provider in your Angular module.
Notes
- Remember to import necessary modules from
@angular/common/http. - The
interceptmethod of theHttpInterceptorinterface receives theHttpRequestandHttpHandleras arguments. - You will need to clone the request to add headers, as requests are immutable.
- The
HttpHandler'shandle()method is used to pass the modified request down the interceptor chain or to the actual HTTP client. - Think about where and how you will register your interceptor within your Angular application. Usually, this is done in the
AppModuleor a shared module.