Skip to Content
Suffering builds character
아카이브20.spring HateoasREST API3.잘 지켜지지 않고 있는 제약조건

3.잘 지켜지지 않고 있는 제약조건

대부분의 운영 중인 시스템들은 보통 모든 REST 제약조건을 준수하고 있지 않음

잘 지켜지지 않고 있는 제약조건은 다음과 같음

1. 일관된 인터페이스(uniform interface)

uniform-interface는 REST 아키텍처의 제약조건 중에서도 대부분 잘 지켜지지 않고 있는 제약조건으로, 크게 네 가지로 구성됨

1-1. 리소스 식별(identification of resources) - 양호

리소스는 URI를 통해 식별될 수 있어야 한다는 것

JSON 응답 값
GET /users/123
{ "id": 123, "name": "gugu", "email": "gugu@example.com" }
  • 리소스는 users라는 컬렉션 안의 123번 사용자라는 식별 가능한 단위로 URI로 표현됨
  • 리소스의 경로는 명사 중심이고 동작(메서드)은 HTTP Method로 분리됨

1-2. 표현을 통한 리소스 조작(manipulation of resources through representations) - 양호

리소스에 대해 수정/삭제 등의 작업을 수행 할 때, HTTP메시지에 표현을 담아 전송하면 된다는 것

JSON 응답 값
PUT /users/123 Content-Type: application/json
{ "name": "yuyu", "email": "yuyu@example.com" }
  • 클라이언트가 서버에 리소스의 새 표현(JSON)을 전달함으로써, 리소스를 수정함
  • 표현(json) 안에 수정하고자 하는 필드가 들어있고, 서버는 이를 기반으로 리소스를 갱신

1-3. 자기 서술적 메시지(self-descriptive messages) - 미비

메시지는 스스로 자신을 설명할 수 있어야 함
→ 클라이언트는 메시지만 보고도 무엇을 의미하는지 파악할 수 있어야 한다는 것

자기 서술적이지 않은 메시지의 예시

JSON 응답 값
POST /scheduled-tasks
{ "uid": "8391", "tp": "2", "dt": "2025-06-20T13:00:00Z", "st": "1" }
  • uid → 사용자 ID인지, 주문 ID인지, 문맥 없이는 알기 어려움
  • tp → 타입? 무엇의 타입? 어떤 값이 어떤 의미인지 불분명
  • dt → 생성일인지 예약일인지?
  • st → 상태? 어떤 상태? 1은 무슨 의미인지? (예: 0: 준비중, 1: 완료?)
  • 또한 Content-type이 빠져있으면 해당 데이터가 무슨 타입인지 파악이 어렵기 때문에 브라우저도 파싱을 잘 못함

자기 서술적인 예시

JSON 응답 값
POST /scheduled-tasks Content-Type: application/json { "userId": "8391", "taskType": "NOTIFICATION", "scheduledAt": "2025-06-20T13:00:00Z", "status": "COMPLETED" }

1-4. 하이퍼링크를 통한 상태 전이(HATEOAS) - 미비

애플리케이션의 상태는 Hyperlink를 통해 전송되어야 한다는 것

HATEOAS가 적용되지 않은 예시

JSON 응답 값
GET /orders/2025 { "id": 2025, "status": "SHIPPED", "items": [...] }
  • 다음에 무엇을 해야 할지 클라이언트가 판단해야 함
    → 서버 변경 시 클라이언트도 수정 필요
JSON 응답 값
GET /orders/2025 { "id": 2025, "status": "SHIPPED", "items": [...], "_links": { "profile": { "href": "/swagger-ui/index.html"}, "self": { "href": "/orders/2025" }, "cancel": { "href": "/orders/2025/cancel", "method": "POST" }, "track": { "href": "/orders/2025/track", "method": "GET" } } }
  • 클라이언트는 서버가 제공하는 링크를 보고, 어떤 행동이 가능한지 알 수 있음
  • 클라이언트의 코드에서는 URI를 하드코딩하지 않아도 됨
    → 유연성과 유지보수성 증가
Last updated on