17 - Interceptor
Introduction
Dans cette quête, tu vas apprendre comment intercepter des requêtes http dans une application angular.
Pour y arriver, tu vas utiliser les Http Interceptor.
Pour cette quête, tu auras besoin d'un projet comportant un service avec un HttpClient qui fonctionne.
Objectifs 🤓
✅ Être en mesure de créer et d'intégrer un interceptor à ton application angular ✅ Comprendre comment interagir sur la réception d'une requête.
Avant de démarrer, assure-toi d'avoir terminé les quêtes suivantes👇
Commençons par quelques définitions
- Un interceptor est un concept qui nous permet d'ajouter des comportements globaux à toutes les requêtes effectuées dans un module.
Par exemple, tu pourrais souhaiter afficher dans la console l'url de chaque requête effectuée pour garder un historique de ce que tu as fait.
-
Un interceptor est une classe qui implémente l'interface
HttpInterceptor. -
Pour implémenter correctement cette interface (ce comportement) tu dois ajouter à ta classe une méthode
intercept. -
La méthode
interceptà 2 paramètres en entrée : uneHttpRequestet unHttpHandler -
Tu dois ajouter ton custom interceptor au module qui t'intéresses.
Éclaircissements
Quand tu fais une requête dans angular, tu utilises le HttpClient.
getData() {
// Création de l'observable
this.http.get('https://jsonplaceholder.typicode.com/todos/1')
// Abonnement à l'observable (et donc déclenchement de la requête)
.subscribe((data) => {
// Réponse du serveur
console.log(data);
});
}
Il faut savoir qu'il y a des étapes cachées entre l'abonnement et la réponse du serveur.
C'est dans ces étapes cachées que tu vas pouvoir glisser ton interceptor.
Création de ton Http Interceptor
Tu ne peux pas t'aider du angular/cli pour générer un interceptor. Il va donc falloir faire le travail à la main.
Tu vas donc créer le fichier suivant: src/app/core/log.interceptor.ts
Cet interceptor est un injectable, tu auras donc :
import { Injectable } from '@angular/core';
@Injectable()
export class LogInterceptor {
}
Maintenant tu vas implémenter l'interface HttpInterceptor à ta classe LogInterceptor.
Assure toi d'importer HttpInterceptor depuis :
// autres imports
import { HttpInterceptor } from '@angular/common/http';
@Injectable()
export class LogInterceptor implements HttpInterceptor {
}
Maintenant si tu utilises VSCode, tu as le droit à un peu de magie. Quand on implémente une interface, cela signifie qu'on s'accorde pour dire que la classe suivra les règles imposées par l'interface.
Dans le cas de HttpInterceptor, la règle imposée est : la méthode intercept.
Heureusement pour nous, VSCode est capable de détecter qu'on ne respecte pas les règles. Si tu cliques sur le nom de ta classe LogInterceptor VSCode te proposera grâce à une ampoule bleu, de générer le code manquant.
Ce qui te donne:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
throw new Error('Method not implemented.');
}
(
Method not implementedsignifie qu'il n'est pas capable de générer le contenu de ta méthode, seulement son enveloppe. )
Retour à notre objectif : logger les urls
@Injectable()
export class LogInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log(req.urlWithParams); // J'affiche l'url avec les params
// Je passe la requête à la suite des interceptors cachés d'angular
// Et je retourne ce résultat pour que la requête ait bien lieu
return next.handle(req);
}
}
Tu peux aller fouiller dans les objets en faisant ctrl+clique sur l'objet (ou clic droit → go to definition). Tu auras ainsi un aperçu de tout ce que contient l'objet HttpRequest.
Exploiter les observable
Dans la partie précédente, tu as ajouté du code à exécuter avant que la requête ne soit effectuée.
Parfois, on souhaite effectuer une action au moment où on obtient la réponse du serveur. Pour gérer ce cas, les observables te faciliteront la tâche.
// ...
// pipe permet d'ajouter des actions à effectuer quand l'observable est résolue
return next.handle(req).pipe(
// tap est un observable qui indique : "Je fais des actions sans modifier la réponse"
tap((response) => {
// On s'assure qu'il s'agit bien d'une réponse http
if (response instanceof HttpResponse) {
// Ici sera le code exécuté à la réponse du serveur
// Dans le cas où tout s'est bien passé
}
});
);
// ...
Dernière étape : renseigner ton interceptor dans AppModule
Tu vas maintenant permettre à ton interceptor de s'intégrer dans le fonctionnement de ton application Angular.
Il faut pour cela ajouter l'objet suivant dans le tableau des providers de ton module :
// ...
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: LogInterceptor,
multi: true
}
],
// ...
Challenge 💪
Mesurer une différence de temps ⌛️
Tu vas devoir créer un interceptor permettant d'afficher la durée d'exécution d'une requête. Pour cela, tu devras notamment te froter aux formats des dates dans Javascript.
Il te faudra :
-
Un service avec une méthode pour faire un get
- Tu peux utiliser ton propre serveur node ou bien cette API publique
-
Un composant (
app.component.tspar exemple) qui appelle la méthode de ton service -
L'interceptor que tu auras écrit
Critères de validation ✅
- La console doit afficher l'URL cible de la requête HTTP
- Une fois que le serveur a répondu, la console doit afficher le temps total qu'à pris la requête à être exécutée.