高瀬博道の技術ブログ

高瀬博道の技術ブログです。

もう2023年になったので、今さらNestJSに入門しようと思う - その17

前回

takasehiromichiex.com

インターセプタのレスポンスマッピング

handle()Observableを返しますが、ストリームにはルートハンドラから返却された値が含まれているので、RxJSのmap()を使用して簡単に変更することができます。

新しいインターセプタを作成しましょう。

$ nest g interceptor interceptor/transform

以下のファイルが作成されました。

src/interceptor/transform/transform.interceptor.ts
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle();
  }
}
src/interceptor/transform/transform.logging.spec.ts
import { TransformInterceptor } from './transform.interceptor';

describe('TransformInterceptor', () => {
  it('should be defined', () => {
    expect(new TransformInterceptor()).toBeDefined();
  });
});

インターセプタを修正します。

src/interceptor/transform/transform.interceptor.ts
import {
  CallHandler,
  ExecutionContext,
  Injectable,
  NestInterceptor,
} from "@nestjs/common";
import { map, Observable } from "rxjs";

export interface Response<T> {
  data: T;
}

@Injectable()
export class TransformInterceptor<T>
  implements NestInterceptor<T, Response<T>>
{
  intercept(
    context: ExecutionContext,
    next: CallHandler
  ): Observable<Response<T>> {
    return next.handle().pipe(map((data) => ({ data })));
  }
}

レスポンスのdataをオブジェクトにして返却しています。

コントローラにバインドします。

src/cats/cats.controller.ts
import { Body, Controller, Get, Post, UseInterceptors } from "@nestjs/common";
import { CreateCatDto } from "src/dto/cat/cat.dto";
import { Cat } from "./cats.interface";
import { CatsService } from "./cats.service";
import { ValidationPipe } from "../pipe/validation/validation.pipe";
import { LoggingInterceptor } from "src/interceptor/logging/logging.interceptor";
import { TransformInterceptor } from "src/interceptor/transform/transform.interceptor";

@Controller("cats")
@UseInterceptors(LoggingInterceptor, TransformInterceptor)
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  create(@Body(new ValidationPipe()) createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }
  @Get()
  findAll(): Cat[] {
    return this.catsService.findAll();
  }
}

postmanで、GET localhost:3000/catsを呼び出すと、以下のように返却されます。

{
    "data": []
}

まとめ

ここまでで、

  • インターセプタのレスポンスマッピングの例

を学びました。

次回も、インターセプタを掘り下げようと思います。

コード

今回のコードは、以下に格納しました。

github.com

takasehiromichiex.com