Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Angular
  3. Le requêtage HTTP
Extrait - Angular Développez vos applications web avec le framework JavaScript de Google (3e édition)
Extraits du livre
Angular Développez vos applications web avec le framework JavaScript de Google (3e édition) Revenir à la page d'achat du livre

Le requêtage HTTP

Introduction

Dans ce chapitre, nous allons voir comment envoyer, récupérer et traiter des données au travers du protocole HTTP. Nous verrons également comment communiquer de manière sécurisée avec ce protocole. Enfin, le sujet des tests sur les éléments utilisant le service HTTP d’Angular sera abordé.

Obtenir et envoyer des données

Afin d’envoyer et de recevoir des données, Angular fournit un module HTTP. Le module HTTP expose plusieurs méthodes permettant d’envoyer et recevoir des données via des requêtes HTTP.

Afin d’utiliser ce module, il faut commencer par l’importer dans le module de l’application. Pour cela, il suffit d’ajouter la classe HttpClientModule dans la propriété imports du décorateur @NgModule du module principal de l’application :

import { BrowserModule } from '@angular/platform-browser'; 
import { NgModule } from '@angular/core'; 
import { HttpClientModule } from '@angular/common/http'; 
import { AppComponent } from './app.component'; 
 
@NgModule({ 
  declarations: [ 
    AppComponent 
  ], 
  imports: [ 
    BrowserModule, 
    HttpClientModule 
  ], 
  bootstrap: [AppComponent] 
}) 
export class AppModule { } 

Le module HttpClientModule enregistre une dépendance sur la classe HttpClient. Une fois ce module importé, il est possible d’injecter cette classe dans tous les éléments ayant besoin d’effectuer des requêtes HTTP.

Les méthodes exposées par ce module correspondent aux verbes HTTP employés pour effectuer la requête. Dans le cas de la récupération de données, le verbe le plus fréquemment utilisé est GET. Il faut donc utiliser la méthode get du module HTTP afin de récupérer des données. Ces méthodes retournent des observables RxJS et rendent donc facile la programmation réactive utilisant des données externes.

Pour plus d’informations concernant les observables...

Transformer des données

Habituellement, la récupération et le traitement des données s’effectuent dans des services, et il est fréquent que le modèle récupéré par l’API et le modèle que nous voulons traiter dans l’application soient différents. Il est alors nécessaire de faire de la projection.

interface Pomme { 
 id: number; 
 name: string; 
} 
 
interface PommeApi { 
 id: number; 
 type: string; 
 color: string; 
} 

Avec RxJS, il est très simple de modifier le type de retour d’un observable tout en restant dans le flux de traitement de celui-ci. Il suffit en effet d’utiliser le pipe map. Afin de l’utiliser, il est nécessaire d’importer l’opérateur map depuis RxJS. Cet opérateur est situé dans rxjs/operators.

import { Injectable } from "@angular/core"; 
import { HttpClient } from "@angular/common/http"; 
import { Observable } from "rxjs"; 
 
import { map } from "rxjs/operators"; 
 
@Injectable({ 
 providedIn: "root" 
}) 
export class PommeService { 
 baseUrl: string = "http://localhost:5000/api"; 
 constructor(private http: HttpClient) {} 
 
 public getPommes(): Observable<Pomme[]> { 
   return this.http.get<PommeApi[]>(`${this.baseUrl}/pommes`).pipe( 
     map((pommeApi: PommeApi[]) => { 
       return projectPommeApisToPommes(pommeApi); 
     }) 
   ); 
 } 
} 
 
export const projectPommeApisToPommes = (pommeApis: PommeApi[]): 
Pomme[] =>...

Communiquer de manière sécurisée

Il arrive souvent que l’API soit sécurisée et nécessite une authentification. Quel que soit le type d’authentification, il est possible de mettre en place des « intercepteurs » pour injecter des headers dans toutes les requêtes. En somme, l’idée est d’intercepter la requête, de la traiter si nécessaire et de la renvoyer.

En supposant que l’authentification soit développée avec un JWT. Nous avons un AuthenticationService qui expose un token que nous devons envoyer dans un header de l’API.

import { Injectable } from '@angular/core'; 
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor }  
from '@angular/common/http'; 
import { Observable } from 'rxjs'; 
import { AuthenticationService } from './auth.service'; 
 
@Injectable() 
export class JwtAuthInterceptor implements HttpInterceptor { 
 constructor(private authService: AuthenticationService) {} 
 
 intercept(request: HttpRequest<any>, next: HttpHandler): 
Observable<HttpEvent<any>> { 
   const token = this.authService.getToken(); 
   if (token) { 
     request = request.clone({ 
       setHeaders: { 
        Authorization: `Bearer ${token}` 
       } 
     }); 
   } 
 
   return next.handle(request); 
 } 

Le JwtAuthInterceptor est une classe qui implémente HttpInterceptor.

Les intercepteurs sont des classes qui peuvent bénéficier de l’injection de dépendances sans problème.

La méthode...

Simuler le requêtage HTTP

Lorsqu’une application Angular est testée, il est courant de vouloir simuler le serveur HTTP pour éviter d’avoir à déployer une API lors de l’exécution des tests. Pour éviter ce comportement, il est possible de bouchonner le service HttpClient de base afin qu’il retourne directement des objets statiques définis dans la méthode de test. Ceci permet de ne pas dépendre des données sur le serveur afin de valider le bon fonctionnement de l’application.

Pour injecter le service à tester dans le test, il faut utiliser l’objet TestBed.

    const service: PommeService = TestBed.get(PommeService); 

Cet objet est disponible dans @angular/core/testing. Il sert à mettre en place un environnement de test. Nous avons besoin du HttpClientModule car le service HttpClient est injecté dans notre PommeService. Pour les problématiques de test, au lieu d’importer le HttpClientModule, nous allons importer le HttpClientTestingModule. Avec ce module, les appels HTTP ne vont pas vraiment être faits, mais uniquement simulés.

Cela doit être réalisés avant chaque test, grâce à beforeEach.

BeforeEach(() => 
 TestBed.configureTestingModule({ 
   imports: [HttpClientTestingModule] 
 }) 
); 

Le module HttpClientTestingModule permet de récupérer une instance de HttpTestingController. Il va nous être très utile pour plusieurs raisons. 

const httpTestingController: HttpTestingController = 
TestBed.get(HttpTestingController); 

Il est possible de s’assurer que des appels HTTP sont faits par le service à tester. 

Ainsi, on peut confirmer que le PommeService souhaite faire un appel GET sur <urlApi>/pommes. En réalité, Angular va s’arrêter juste...