재시도된 생성 요청이 같은 업무 결과를 반환하게 설계합니다.
네트워크 재시도와 중복 클릭은 같은 명령을 여러 번 보낼 수 있습니다. 사용자·작업 범위의 idempotency key와 결과를 원자적으로 저장합니다.
key 만료와 payload 불일치 정책을 정하고 DB unique constraint로 race를 막습니다.
GET의 멱등성과 POST 명령의 중복 방지 요구를 구분합니다.
프로세스 메모리 Map만 운영 중복 방지 저장소로 사용하면 재시작과 다중 instance에서 깨집니다.
로컬 프로젝트에서 확인해보세요같은 key에 다른 title이 오면 409를 반환하세요.
import "reflect-metadata";
import { Controller, Get, Headers, Module, Post } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";
@Controller()
class AppController {
private readonly results = new Map<string, object>();
@Get() home() {
return { hint: "POST /courses with idempotency-key header" };
}
@Post("courses") create(@Headers("idempotency-key") key = "demo") {
if (this.results.has(key)) return this.results.get(key);
const result = { id: crypto.randomUUID(), created: true };
this.results.set(key, result);
return result;
}
}
@Module({ controllers: [AppController] })
class AppModule {}
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(4173, "0.0.0.0");
}
bootstrap();