Skip to Content
Suffering builds character
아카이브20.spring HateoasREST API2.REST 아키텍처의 제약조건

2.REST 아키텍처의 제약조건

1. REST의 제약조건

REST 아키텍처를 지키기 위해서는 로이 필딩이 제안한 제약조건들을 모두 충족해야 함

1-1. 클라이언트-서버 구조(client-server)

  • 클라이언트와 서버의 역할을 명확히 분리하여 각자의 책임을 독립적으로 수행
  • 클라이언트는 사용자 인터페이스(UI)나 UX에 집중
  • 서버는 데이터 처리, 저장, 비즈니스 로직 수행
  • 독립적 개발 및 배포 가능 (서버가 변경되어도 클라이언트의 수정이 불필요, 반대도 마찬가지)

1-2. 무상태성(stateless)

  • 각 요청은 독립적이며, 서버는 이전 요청의 컨텍스트를 저장하지 않음
  • 요청마다 필요한 모든 정보를 담아서 전달 (ex. 토큰)
  • 서버가 특정 사용자 상태를 기억하지 않으므로 부하 분산이나 서버 증설이 쉬움
    ex. 매 요청에 JWT 토큰을 포함해서 인증
    → 서버는 저장할 필요 없이 디코딩만 하면 됨

1-3. 캐싱(cache)

  • 서버는 응답이 캐시될 수 있는지 명시적으로 알려야 하며, HTTP 캐싱 메커니즘을 활용해야 함
  • 클라이언트, 프록시 서버, CDN 등에서 응답을 재사용 가능하게 하여 네트워크 부하와 응답시간을 줄임으로써 성능 향상, 네트워크 비용 감소

ex. Cache-Control: max-age=3600
→ 1시간 동안 같은 요청은 캐시된 응답으로 처리

1-4. 공식 인터페이스(uniform interface)

  • 시스템 전반에 걸쳐 일관된 방식으로 리소스와 상호작용

  • URI를 통해 리소스를 식별 (ex. /users/123)

  • 표현을 통한 조작(ex. JSON/XML로 상태 전달)

  • 자기서술적 메시지(ex. 메시지 안에 컨텐츠에 대한 정보 포함 Content-Type, Accept 등)

  • HATEOAS: 응답 내 링크 포함

JSON 포맷
"links": { "next": "/page/2" }
  • 표준화된 상호작용 방식으로 학습 비용과 시스템 결합도를 줄임

1-5. 계층화된 시스템(layered system)

  • 클라이언트는 중간 서버(프록시, 게이트웨이, 로드 밸런서 등)를 의식하지 않고 서버와 통신
  • 계층 구조를 통해 보안, 로깅, 캐싱, 부하 분산 등의 기능을 중간 계층이 처리 가능
  • 구조적 유연성 확보, 보안성 향상, 확장성 증가

ex. API Gateway를 통해 인증, 로깅
→ 실제 백엔드 서버는 비즈니스 로직만 담당

  • 코드를 통한 조작(code on demand)
  • 서버가 클라이언트에 코드를 전송하여 실행하게 할 수 있음 (ex. 자바스크립트)
  • 클라이언트 기능을 동적으로 확장할 수 있는 유일한 제약 조건
  • REST에서 유일하게 선택적으로 적용 가능
  • 클라이언트는 서버가 전송한 코드를 실행함으로써 동적으로 기능을 확보할 수 있음

ex. 브라우저가 서버로부터 받은 JS를 실행하여 동적인 페이지 생성

Last updated on