9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-05-16

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 { }

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

参考リンク

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?