Nest.js で送信する前にレスポンスをフォーマットするにはどうすればいいですか? 質問する

Nest.js で送信する前にレスポンスをフォーマットするにはどうすればいいですか? 質問する

ドキュメントに従って、レスポンス マッピング用のインターセプターを追加することができました。

応答に対して一貫した json 形式の出力が必要です。

インターセプターまたはこのアプローチよりも優れた他の方法でこれを実現するにはどうすればよいでしょうか。

{
  "statusCode": 201,
  "message": "Custom Dynamic Message"
  "data": {
     // properties
     meta: {}
  }
}

変換インターセプター.ts

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Response<T> {
  statusCode: number;
  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) => ({
          statusCode: context.switchToHttp().getResponse().statusCode,
          data,
        })),
      );
  }
}

アプリ.コントローラ.ts

export class AppController {
      @Post('login')
      @UseGuards(AuthGuard('local'))
      @ApiOperation({ summary: 'Login user' })
      @ApiBody({ type: LoginDto })
      @ApiOkResponse({ content: { 'application/json': {} } })
      @UseInterceptors(TransformInterceptor)
      async login(@Request() req) {
        const result = await this.authService.login(req.user);
        return { message: 'Thank you!', result };
      }
}

ベストアンサー1

コントローラーの応答と全体的なインターセプターの応答で何を実行しているかを理解している場合、実行できることは同様のことです。

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Response<T> {
  statusCode: number;
  message: string;
  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) => ({
          statusCode: context.switchToHttp().getResponse().statusCode,
          message: data.message
          data: {
            result: data.result,
            meta: {} // if this is supposed to be the actual return then replace {} with data.result
          }
        })),
      );
  }
}

コントローラーの戻り値は のままにしておきます{message: 'Custom message', result}

もう 1 つのオプションは、より多くの事前準備が必要になりますが、よりクリーンなコードを可能にする可能性があり、クラスとメソッドから値 (メッセージ) を反映し、リフレクタを挿入した後にインターセプターでその値を取得するカスタム デコレータを作成することですが、この場合も、セットアップにより多くの事前の労力がかかります。

おすすめ記事