序章
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);
}
}