REST API를 설계하다 보면 `POST` 요청으로 리소스를 생성한 뒤에는 보통 `201 CREATED`로 응답을 보내는데 이때 `Location` 헤더를 보내는게 관례다.
HTTP/1.1 201 Created
Location: /themes/123
Spring의 `ResponseEntity.created()`에서도 무조건 URI를 넣게 되어있다.

여기서 한가지 의문이 들었다. “201 Created면 무조건 Location 헤더를 내려야 하나?”
결론부터 말하면:
- 단건 조회 API가 존재한다면 Location 헤더를 제공하는 것이 REST스럽다
- 하지만 단건 조회 API가 없다면 굳이 Location을 내려주는 건 오히려 혼란을 줄 수 있다
이 글에서는 왜 그런지, 그리고 현실적으로 어떤 방식이 더 좋은지 정리해본다.
✅ 일반적인 201 Created 응답
보통 REST 문서에서는 리소스 생성 성공 시 다음처럼 설명한다.
HTTP/1.1 201 Created
Location: /themes/123
의미는 명확하다.
- 서버가 새로운 리소스를 생성했고
- 해당 리소스는 `/themes/123` 에서 조회 가능하다는 뜻이다.
즉, Location 헤더는 단순한 식별자가 아니라: “이 URI로 가면 방금 생성된 리소스를 조회할 수 있음” 이라는 의미를 가진다.
✅ 그런데 단건 조회 API가 없다면?
예를 들어 `POST /themes` 는 존재하지만 `GET /themes/{id}` 는 존재하지 않는 경우가 있다.
이런 상황에서 억지로 `Location: /themes/123` 를 내려주면 어떻게 될까?
클라이언트는 자연스럽게 이렇게 생각한다. “아, 여기로 GET 요청 보내면 되겠네?”
하지만 실제로는 단건 조회 API가 없기 때문에 404 Not Found가 발생한다.
따라서 조회 불가능한 URI를 Location으로 제공하는 건 API 사용자를 혼란스럽게 만들 수 있다.
✅ 그렇다면 어떻게 하는 게 좋을까?
이런 경우에는 Location 대신: 응답 바디에 생성된 리소스의 식별자(id)를 내려주는 방식이 훨씬 현실적이다.
예시:
HTTP/1.1 201
Content-Type: application/json
{
"id": 1,
"name": "공포",
"description" : "무서움",
"thumbnail" : "url"
}
이 방식의 장점은 명확하다.
- 클라이언트가 생성 결과를 추적 가능
- 존재하지 않는 URI를 암시하지 않음
- API 스펙이 실제 동작과 일치함
- 불필요한 REST 형식주의를 피할 수 있음
중요한 건 “REST 원칙”보다 “일관된 의미”라고 생각한다.
“201 Created면 Location 헤더를 반드시 넣어야 한다”라고 생각하기 쉬운데, 핵심은 클라이언트가 다음 행동을 명확히 이해할 수 있는가, 응답이 실제 API 동작과 일치하는가라고 생각한다.
✅ 정리
1. 조회 가능하면 Location
201 Created
Location: /themes/1
2. 조회 API 없으면 ID만 반환
HTTP/1.1 201
Content-Type: application/json
{
"id": 1,
"name": "공포",
"description" : "무서움",
"thumbnail" : "url"
}'우테코 8기 > 본과정 탐구 일지' 카테고리의 다른 글
| [레벨 2 - 방탈출 사용자] 유니크 제약 조건, 서비스에서 검증할까? 리포지토리에서 처리할까? (0) | 2026.05.10 |
|---|---|
| [레벨2 - 방탈출 사용자] 삭제할 리소스가 없을 때도 204 No Content를 내려도 될까? (0) | 2026.05.10 |
| [레벨 2 - 방탈출 관리자] 테이블 구조 변경으로 인한 코드 수정을 효율적으로 하기 (0) | 2026.05.01 |
| [레벨 1 장기] 안 좋은 코드습관 고치기 (1) | 2026.04.12 |
| [레벨1 선택미션] 《객체지향의 사실과 오해》 읽고 장기 도메인 모델 설계하기 (0) | 2026.03.22 |