序章
AngularのHttpInterceptor
は、発信リクエストまたは着信応答をインターセプトまたはミュートするメカニズムを提供します。 これらは、フロントエンドを除いて、Expressのようなフレームワークを備えたミドルウェアの概念と非常によく似ています。 インターセプターは、キャッシングやロギングなどの機能に非常に役立ちます。
注:ここの内容はAngular4.3以降に適用されます。
この記事では、AngularプロジェクトでのHttpInterceptor
の使用について学習します。
基本設定
インターセプターを実装するには、注入可能でHttpInterceptor
を実装するクラスを作成する必要があります。 クラスは、HttpInterceptor
を正しく実装するために、intercept
メソッドを定義する必要があります。 インターセプトメソッドは、request
とnext
の2つの引数を取り、タイプHttpEvent
のオブザーバブルを返します。
request
はリクエストオブジェクト自体であり、タイプはHttpRequest
です。next
は、タイプHttpHandler
のHTTPハンドラーです。 ハンドラーにはhandle
メソッドがあり、目的のHttpEvent
オブザーバブルを返します。
以下は、基本的なインターセプターの実装です。 この特定のインターセプターは、単にRxJS do
演算子を使用して、要求のfilter
クエリパラメーターの値とHttpEvent
ステータスをコンソールに記録します。 do
演算子は、次のような副作用に役立ちます。
インターセプター/my.interceptor.ts
import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/do'; @Injectable() export class MyInterceptor implements HttpInterceptor { intercept( req: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> { return next.handle(req).do(evt => { if (evt instanceof HttpResponse) { console.log('---> status:', evt.status); console.log('---> filter:', req.params.get('filter')); } });
インターセプターを接続するには、HTTP_INTERCEPTORS
トークンを使用してアプリモジュールまたは機能モジュールでインターセプターを提供しましょう。
app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { MyInterceptor } from './interceptors/my.interceptor';
複数の迎撃機
次のようなもので複数のインターセプターを定義できます。
providers: [ { provide: HTTP_INTERCEPTORS, useClass: MyInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: MySecondInterceptor, multi: true } ],
インターセプターは、提供された順序で呼び出されます。 したがって、上記の場合、MyInterceptor
は最初にHTTP要求を処理します。
リクエストの変更
HttpRequest
オブジェクトは不変であるため、オブジェクトを変更するには、最初にコピーを作成し、次にコピーを変更して、変更したコピーに対してhandle
を呼び出す必要があります。 リクエストオブジェクトのclone
メソッドは、まさにそれを行うのに便利です。 filter
クエリパラメータをcompleted
の値に設定する単純なインターセプタを次に示します。
@Injectable() export class MyInterceptor implements HttpInterceptor { intercept( req: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> { const duplicate = req.clone({ params: req.params.set('filter', 'completed') }); return next.handle(duplicate); } }
そして、これがリクエストの本文にあるpizza
という単語のすべての出現をピザ絵文字に変更するインターセプターの最後の例です(🍕)。 本文のないリクエストは、return next.handle(req)
を使用して元のリクエストを返すことでパススルーされます。
@Injectable() export class MyInterceptor implements HttpInterceptor { intercept( req: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> { if (req.body) { const duplicate = req.clone({ body: req.body.replace(/pizza/gi, '🍕') }); return next.handle(duplicate); } return next.handle(req); } }