Nest.jsでレスポンスのマッピングをする
2022-12-11
2 years ago
開発環境
- NestJS
- Prisma
前提
ORMはPrismaを利用しています。
本題
はじめに
サインアップ、ログインなどユーザー周りの認証を作っている中で、認証をパスしたユーザーのオブジェクトをクライアント側にレスポンスするケースはあると思います。
そんな時、パスワードなどはレスポンスに含めたくないと思います。
今回はそんなレスポンスデータの変更を行うサンプルとして、公式を参考に作ります。
選択肢
- 特定のフィールド(今回だとpassword)をコントローラごとに取り除く → DRYでない、エラーの余地が多そうなので X
- class-transformerを利用する方法 → 今回Prismaを利用してますが、こちらの方法もあるようです。ただ今回は X
- カスタムインターセプターを作る → 公式ドキュメントもあったのでこちらでやってみます
実装
- interceptorのファイルを作成し、passwordを取り除く
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export interface Response<T> {
data: T;
}
@Injectable()
export class RemovePasswordInterceptor<T>
implements NestInterceptor<T, Response<T>>
{
intercept(
context: ExecutionContext,
next: CallHandler
): Observable<Response<T>> {
return next.handle().pipe(
map((value) => {
if (value?.password) {
value.password = undefined;
}
return value;
})
);
}
}
- グローバルに設定する
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { RemovePasswordInterceptor } from './auth/interceptor/auth.interceptor';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
# 追加
app.useGlobalInterceptors(new RemovePasswordInterceptor());
await app.listen(3000);
}
bootstrap();
さいごに
1 ~ 2 で簡単に特定のフィールド(今回はpassword)をレスポンスから除外できました。
サンプルではグローバルに設定していますが、コントローラレベル、メソッドレベルで設定できるので色々と活用できそうです。