Interceptors - AngularBuildUp/angular-microworkshops-authorization GitHub Wiki
They are like middlewares. When application makes a request, they can transform it before is send to the server. They can also transform the response that is returned before the application sees it.
Create a class which implements HttpInterceptor
and has an intercept
method. This method transforms a request into an Observable
that eventually returns the response.
next
is an HttpHandler
, an interface that similar to intercept
method, transforms a request into an Observable
for the response. In an interceptor, next
always represents the next interceptor in the chain and if any or the final backend if there are no more interceptors.
To wire up in the AppModule
you register it to the providers
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: YourClassName,
multi: true
}]
The multi: true
option is required and tells Angular that HTTP_INTERCEPTORS
is an array of values rather than a single value.
Interceptors work at a lower level than the HttpClient
interface. A single request can generate multiple events, including upload and download progress events. The HttpResponse
is actually an event itself with a type of HttpEventType.HttpResponseEvent
under the hood.
When you provide multiple interceptors in an application, Angular applies them in order that you provided them.
HttpRequest
and HttpResponse
classes are immutable. Because the app may retry requests, the interceptor chain may process an individual request multiple times. If requests were mutable, a retried request would be different than the original. Immutability ensures the interceptors see the same request for each try.
It is invalid to mutate the request body within an interceptor, but this is not checked by the type system.
If you need to mutate the request body, copy it, mutate the copy and then use clone
to copy the request and set the new body.
Example:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const dupReq = req.clone();
// change the URL and replace http:// with https://
const secureReq = req.clone({ url: req.url.replace("http://", "https://") })
}
You clone the request when you want to mutate it and you pass it to the next.handle()
.
You can peak at the response when you get it back from an interceptor. Consider the following example, that logs how much time it takes for a request/response pair.
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
cons started = Date.now();
return next.handle(req)
.do(event => {
if(event instanceof HttpResponse) {
const elapsed = Date.now() - started;
console.log(`Took ${elapsed} for ${req.urlWithParams}`)
}
})
}