생성 API가 전부 200을 돌려주고 있어서 정리한 기준
문제 발생
모든 성공 응답이 200 OK에 { "success": true } 형태였습니다. 클라이언트는 "만들어졌는지", "큐에 들어갔을 뿐인지", "삭제가 끝났는지"를 본문 필드로 구분해야 했고, 새 엔드포인트마다 그 규칙을 다시 물어봐야 했습니다.
원인 분석
HTTP가 이미 그 구분을 정의해두고 있습니다. RFC 9110의 정의를 그대로 보면 세 코드의 의미가 겹치지 않습니다.
- 201 (Created) — 요청이 성공했고 새 리소스가 생성되었으며, 새로 생성된 리소스가 응답의 Location 헤더 필드로 식별된다는 뜻입니다. 즉 201은
Location과 짝입니다. - 202 (Accepted) — 요청이 처리를 위해 접수되었지만 처리가 완료되지는 않았다는 뜻이고, 명세는 한 걸음 더 나갑니다 — 실제 처리 시점에 허용되지 않을 수도 있으므로 결국 수행될 수도, 되지 않을 수도 있다.
- 204 (No Content) — 서버가 요청을 성공적으로 이행했고 응답 메시지 본문으로 보낼 추가 콘텐츠가 없다는 뜻입니다.
모든 것을 200으로 돌려주면 이 정보가 전부 본문 규약으로 옮겨가고, 그 규약은 서비스마다 달라집니다.
해결 방안
- 생성에는 201과
Location을 함께 보냅니다.
HTTP/1.1 201 Created
Location: /posts/react-server-component-머꼬-a1b2c3d4
Content-Type: application/json
{ "slug": "react-server-component-머꼬-a1b2c3d4" }- 비동기 처리에는 202를 씁니다. 큐에 넣고 나중에 처리하는 작업이 여기 해당합니다. 명세가 "수행되지 않을 수도 있다"고 적은 만큼, 상태를 조회할 방법을 함께 줍니다.
HTTP/1.1 202 Accepted
Location: /jobs/8f2c-
돌려줄 게 없으면 204입니다. 삭제 성공이 대표적입니다. 다만 클라이언트가 갱신된 리소스를 필요로 한다면 200 + 본문이 더 친절합니다 — 왕복 한 번을 줄이는 선택입니다.
-
오류도 코드로 말합니다. 200에
{ "error": ... }를 담으면 캐시·프록시·클라이언트 기본 동작이 전부 어긋납니다. 오류 본문 형식은 RFC 9457(problem+json)을 씁니다. -
문서화보다 일관성이 먼저입니다. 팀에서 "생성=201+Location, 비동기=202, 본문 없음=204"만 정해도 새 엔드포인트를 볼 때 물어볼 것이 사라집니다.
-
기존 엔드포인트를 한 번에 바꾸지 않습니다. 상태 코드는 계약입니다. 새 엔드포인트부터 적용하고, 기존 것은 클라이언트 마이그레이션과 함께 옮깁니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.