[Angular]Interceptor(インターセプター)の介入をする


Angularにおいて、HTTP通信周りの共通処理を仕込みたいときにInterceptor(インターセプター)という仕組みを使います。

例えば

  • HTTP通信のすべてのヘッダーに認証トークンを付与したいとき
  • 通信エラー時の処理を共通で設定したい
  • 通信ログを残したい

といった使い方ができます。

複数のinterceptorが使えるようですが、それはこちらに例がありますので、今回は単一のinterceptorで実装していきます。

Angular 9.1.4で実証しました。

Interceptorを定義する

まず、適当なディレクトリに共通処理の実装を含むhttp-interceptors.tsというファイルを作ります。
リクエスト、レスポンスに介入するコードはそれぞれ以下の通りです。

リクエストに介入する

共通のヘッダーを付与したい場合はこちら

http-interceptors.ts
@Injectable()
export class NoopInterceptor implements HttpInterceptor {
    constructor(private authService: AuthService) {}
    intercept(
        req: HttpRequest<any>,
        next: HttpHandler
    ): Observable<HttpEvent<any>> {
        const newReq = req.clone(
            {headers: req.headers.set('Authorization', this.authService.authToken)}
        );
        // cloneされてヘッダーを付与したリクエストを次の処理に引き渡す
        return next.handle(newReq);
    }
}

レスポンスに介入する

リクエストに介入するのと同じくhttp-interceptors.tsに記述できます。
ファイルは分けてもいいですし、リクエストの介入と一緒に書いてもいいです。
返り値にpipeすることで介入します。

http-interceptors.ts
import { tap } from 'rxjs/operator';

@Injectable()
export class LoggingInterceptor implements HttpInterceptor {

  constructor(private logger: Logger) {}

  intercept(
    req: HttpRequest<any>, 
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(
            // tapオペレータでレスポンスの流れを傍受する
            tap(resp => {
                // リクエスト成功時のログ出力
                console.log(resp);
            },
            error => {
                // エラー時の共通処理やログ出力
                console.error(error);
            }),
        );
  }
}

定義したinterceptorをproviderに登録する

定義しただけでは呼び出されないので、app.module.tsのproviderに定義します。

app.module.ts

@NgModule({
  declarations: [
    AppComponent,
    // AnyComponent
  ],
  imports: [
    HttpClientModule,
    FormsModule,
    AppRoutingModule
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: Interceptor, multi: true }
  ],
  bootstrap: [AppComponent],
  entryComponents: []
})
export class AppModule { }

これで、同じエラー処理を書かずに済みます。

参考リンク