シリアライゼーションは、オブジェクトがレスポンスで送信されるJSONにどのように変換されるかを制御します。重要なのは、機密フィールド(パスワードなど)を除外し、出力を成形することです。NestJSはClassSerializerInterceptorとclass-transformerデコレータで処理します。
問題:機密データの漏洩
()
() {
..(id);
}
データベースエンティティを直接返すと、クライアントに到達してはいけないフィールド(パスワードハッシュ、内部フラグ、トークン)が露出する可能性があり、深刻なセキュリティ/プライバシーの問題です。
import { Exclude } from "class-transformer";
export class User {
id: number;
name: string;
email: string;
@Exclude() // this field is REMOVED from responses
password: string;
}
// enable the serializer interceptor (globally or per-controller)
@UseInterceptors(ClassSerializerInterceptor)
@Controller("users")
export class UsersController {
@Get(":id")
findOne(@Param("id") id): User {
return this.usersService.findOne(id); // password is automatically stripped
}
}
// or globally: app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)))
ClassSerializerInterceptorはレスポンスをシリアライズするときにclass-transformerデコレータを適用するため、@Exclude()フィールドは自動的に削除されます。ただし、クラスインスタンスを返す場合に限ります(プレーンオブジェクトではなく)。
export class User {
@Expose() id: number; // explicitly include (with excludeAll strategy)
@Exclude() password: string; // remove from output
@Expose({ name: "full_name" }) // rename in the output
name: string;
@Transform(({ value }) => value.toUpperCase()) // transform the value
code: string;
@Exclude({ toPlainOnly: true }) // exclude only when serializing OUT (not on input)
internalField: string;
}
// ⚠️ the interceptor only transforms CLASS INSTANCES — plain objects pass through unchanged
return new User(data); // ✅ decorators apply
return plainToInstance(User, data); // ✅ convert a plain object to an instance
return { ...data }; // ❌ plain object — @Exclude is IGNORED!
一般的な落とし穴:シリアライゼーションデコレータは実際のクラスインスタンスでのみ機能するため、インスタンスを返す必要があります(ORMエンティティは通常インスタンス;手動で作成したプレーンオブジェクトは変換が必要)。
Instead of decorating entities, map to a separate Response DTO containing only the
fields meant for the client — explicit, decoupled from the DB model, and very safe.
レスポンスシリアライゼーションの制御は、セキュリティとクリーンなAPI設計の両方に重要です。
最も重要な理由は、機密データ漏洩の防止です。データベースエンティティを直接返すと、パスワードハッシュ、内部フィールド、トークン、またはクライアントに到達してはいけない他のデータが露出する可能性があり、一般的で深刻な脆弱性です。
NestJSのClassSerializerInterceptorとclass-transformerデコレータ(@Exclude、@Expose、@Transform)は、レスポンスを形成するためのクリーンで宣言的な方法を提供します。除外フィールドを自動的に削除し、名前変更し、値を変換します。
これは、ユーザーやドメインデータを返す任意のAPIの日常的な重要な知識です。重要な落とし穴は、シリアライゼーションはクラスインスタンスでのみ機能し、プレーンオブジェクトでは機能しないこと(「パスワードがまだ表示されている理由は?」というバグの頻繁な原因)で、実践的に重要です。
さらに価値があるのは、専用レスポンスDTOの代替パターン(エンティティをクライアント安全なフィールドのみを含む明示的な出力クラスにマッピング)を認識することです。これはAPIコントラクトをデータベースモデルから分離し、機密データの最も安全なアプローチです。
シリアライゼーションを適切に制御することは、セキュアでよく設計されたNestJS APIの特徴であり、非公開データを処理する実際のアプリケーションで頻繁に関連する懸念事項です。