8. Interceptors
インターセプターの役割
インターセプターは、リクエストとレスポンスの処理前後に追加のロジックを挿入するために使用されます。主にレスポンスの変換、エラーハンドリング、ログ記録、キャッシュなどに利用されます。インターセプターは、AOP(Aspect-Oriented Programming、アスペクト指向プログラミング)のように動作し、リクエストとレスポンスのライフサイクルにフックを提供します。
基本的なインターセプターの使用方法
新しいインターセプターを作成するには、@Injectable
デコレーターを使用してクラスを定義し、NestInterceptor
インターフェースを実装します。
基本的なインターセプターの例
以下は基本的なインターセプターの例です:
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable()
export class TransformInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next
.handle()
.pipe(
map(data => ({ data })),
);
}
}
インターセプターの登録
インターセプターをコントローラーまたは特定のハンドラに適用するには、@UseInterceptors
デコレーターを使用します。
import { Controller, Get, UseInterceptors } from '@nestjs/common';
import { TransformInterceptor } from './transform.interceptor';
@Controller('cats')
@UseInterceptors(TransformInterceptor)
export class CatsController {
@Get()
findAll(): string {
return 'This action returns all cats';
}
}
グローバルインターセプター
アプリケーション全体にインターセプターを適用する場合は、グローバルインターセプターとして登録します。
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { TransformInterceptor } from './transform.interceptor';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new TransformInterceptor());
await app.listen(3000);
}
bootstrap();
カスタムインターセプターの実装例
レスポンス変換インターセプター
以下はレスポンスを標準形式に変換するカスタムインターセプターの例です:
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable()
export class TransformInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next
.handle()
.pipe(
map(data => ({ status: 'success', data })),
);
}
}
エラーハンドリングインターセプター
以下はリクエストのエラーハンドリングを行うカスタムインタ ーセプターの例です:
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, BadGatewayException } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next
.handle()
.pipe(
catchError(err => throwError(new BadGatewayException())),
);
}
}
ログインターセプター
以下はリクエストとレスポンスのログを記録するカスタムインターセプターの例です:
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
console.log('Before...');
const now = Date.now();
return next
.handle()
.pipe(
tap(() => console.log(`After... ${Date.now() - now}ms`)),
);
}
}
これで、インターセプターの基本的な役割と使用方法について理解できました。次のセクションでは、パイプの役割と使用方法について説明します。