開発覚書はてな版

個人的な開発関連の備忘録

【Angular】HttpInterceptorの実行順序

概要

HttpInterceptorを複数登録した場合の実行順序は以下の通りです。
リクエストはproviders登録の昇順、レスポンスはproviders登録の降順に実行されます。

AInterceptor, BInterceptorの順で登録した場合、

  1. Aのリクエスト前処理
  2. Bのリクエスト前処理
  3. Bのレスポンス処理
  4. Aのレスポンス処理

動作環境

  • Angular 6.0.0
  • TypeScript 2.7.x

サンプルソース

interceptor定義
import { Injectable } from '@angular/core';
import {
  HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse
} from '@angular/common/http';

import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class AInterceptor implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        console.log('A - start');
        return next.handle(req).pipe(
            tap(event => {
                if (event instanceof HttpResponse) {
                    console.log('A - end');
                }
            })
        );
    }
}

@Injectable()
export class BInterceptor implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        console.log('B - start');
        return next.handle(req).pipe(
            tap(event => {
                if (event instanceof HttpResponse) {
                    console.log('B - end');
                }
            })
        );
    }
}
NgModule定義
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

import { AInterceptor, BInterceptor } from './ext';

@NgModule({
    imports: [
        BrowserModule,
        HttpClientModule
    ],
    providers: [
        { provide: HTTP_INTERCEPTORS, useClass: AInterceptor, multi: true },
        { provide: HTTP_INTERCEPTORS, useClass: BInterceptor, multi: true },
    ]
})
export class AppModule { }
実行結果

f:id:kakkoya:20180612210455p:plain

参考URL