HTTP를 원래 설계 의도대로 사용하는 아키텍처 스타일 (REpresentational State Transfer). 로이 필딩의 2000년 박사 논문에서 나왔다.
여섯 가지 제약
| 제약 | 뜻 |
|---|---|
| 클라이언트-서버 | 관심사 분리. 각자 독립적으로 진화 |
| 무상태(Stateless) | 요청에 필요한 정보가 다 들어 있어야 한다 |
| 캐시 가능 | 응답이 캐시 가능한지 명시 |
| 계층화 | 중간에 프록시·게이트웨이가 끼어도 무방 |
| 균일한 인터페이스 | 자원 식별, 표현을 통한 조작, 자기 서술 메시지, HATEOAS |
| 코드 온 디맨드(선택) | 서버가 실행 코드를 보낼 수 있음 |
무상태가 왜 중요한가
-
상태가 있으면
-
그 사용자의 요청은 특정 서버로만 보내야 한다 (세션 고정)
-
서버를 늘려도 균등하게 못 나눈다
-
서버가 죽으면 그 세션이 통째로 사라진다
-
무상태면
-
어느 서버로 보내도 동일하게 처리된다 → 수평 확장이 자유롭다
"확장성의 근거가 무상태" 라는 연결을 말할 수 있어야 한다.
자원 중심 설계
❌ 동사 중심 (RPC 스타일) POST /getUser?id=1 POST /createOrder POST /deleteOrder
✅ 자원(명사) + HTTP 메서드
- GET — /users/1
- POST — /orders DELETE /orders/1
행위는 HTTP 메서드가 표현하고, URI는 자원만 가리킨다.
-
/users — 컬렉션
-
/users/1 — 단일 자원
-
/users/1/orders — 하위 자원
-
/users/1/orders/5 — 하위 자원 단일
-
복수형 명사
-
소문자, 하이픈(-) 사용 (언더스코어 X)
-
끝에 슬래시 없음
-
파일 확장자 없음 (Accept 헤더로 협상)
상태 코드를 제대로 쓴다
| 코드 | 언제 |
|---|---|
| 200 OK | 조회·수정 성공 |
| 201 Created | 생성 성공. Location 헤더에 새 자원 URI |
| 204 No Content | 성공했지만 본문 없음(삭제) |
| 400 Bad Request | 요청 형식 오류 |
| 401 / 403 | 인증 실패 / 인가 실패 |
| 404 Not Found | 자원 없음 |
| 409 Conflict | 상태 충돌(중복 등록, 낙관적 락 실패) |
| 422 | 형식은 맞지만 의미상 처리 불가 |
| 429 Too Many Requests | rate limit |
| 500 / 503 | 서버 오류 / 일시적 불가 |
❌ 모든 응답을 200으로 주고 본문에 {"success": false}
- HTTP의 의미 체계를 버리는 것. 캐시·프록시·클라이언트가 판단할 수 없다
HATEOAS — 거의 지켜지지 않는 제약
응답에 다음에 할 수 있는 행동의 링크를 포함하는 것이다.
{
"id": 1, "status": "PENDING",
"_links": {
"self": { "href": "/orders/1" },
"cancel": { "href": "/orders/1/cancel", "method": "POST" }
}
}
클라이언트가 URI를 하드코딩하지 않고 링크를 따라가게 만드는 것이 취지다. 실무에서는 거의 안 쓴다 — 구현 비용이 크고 클라이언트가 이를 활용하도록 만들기 어렵기 때문이다.
"사실 대부분의 API는 REST가 아니다"
필딩 본인이 HATEOAS 없이 REST라고 부르는 것을 비판했다. 리처드슨 성숙도 모델로 보면
레벨 0 : HTTP를 전송 수단으로만 사용 (모두 POST /api) 레벨 1 : 자원 도입 (/users, /orders)
- 레벨 2 : HTTP 메서드와 상태 코드 활용 — ← 실무 API 대부분이 여기
- 레벨 3 : HATEOAS — ← 진짜 REST
면접에서는 "레벨 2까지가 현실적이고, 그것으로도 대부분의 이점을 얻는다" 고 정리하면서, 무엇을 지키고 무엇을 타협했는지 말하는 편이 좋다.
실무에서 자주 하는 타협
-
POST /orders/1/cancel — # 순수 REST는 PATCH로 상태 변경이지만
-
행위가 명확해 가독성이 낫다
-
-
GET — /users/search?q=… # 검색은 자원으로 표현하기 애매하다 규칙을 아는 상태에서 의도적으로 타협하는 것과 모르고 어기는 것은 다르다.