이것은 왜 REST가 아닌가? REST API에 대한 정의와 설계

REST?

  • REST는 생각보다 오래된 개념이다. 2000년 Roy Fielding의 논문으로부터 시작된다. http 1.0 이후 새로운 소프트웨어의 아키텍쳐로서 REST가 제안된다. 참고로 로이필딩은 http 1.1의 주요 저자 중 한 명이다.
  • REST는 일종의 아키텍쳐이자 규칙이다. http 통신을 아래 6가지의 REST 원칙에 따라 구축하는 것이 주요 목표이다.

REST의 6가지 원칙

  • 인터페이스 일관성(Uniform Interface): 자원에 대하여 통일되고 한정된 일관적인 인터페이스를 통해 수행한다.
  • 무상태(Stateless): 각 요청 간 클라이언트의 컨텍스트가 서버에 저장되어서는 안 된다.
  • 캐시 처리 가능(Cacheable): 클라이언트는 응답을 캐싱할 수 있어야 한다. 잘 관리되는 캐싱은 클라이언트-서버 간 상호작용을 부분적으로 또는 완전하게 제거하여 scalability와 성능을 향상시킨다.
  • 계층화(Layered System): 클라이언트는 보통 대상 서버에 직접 연결되었는지, 또는 중간 서버를 통해 연결되었는지를 알 수 없다. 중간 서버는 로드 밸런싱 기능이나 공유 캐시 기능을 제공함으로써 시스템 규모 확장성을 향상시키는 데 유용하다.
  • 클라이언트/서버 구조(Client-Server) : 아키텍처를 단순화시키고 작은 단위로 분리(decouple)함으로써 클라이언트-서버의 각 파트가 독립적으로 개선될 수 있도록 해준다..
  • Code on demand (optional) - 자바 애플릿이나 자바스크립트의 제공을 통해 서버가 클라이언트가 실행시킬 수 있는 로직을 전송하여 기능을 확장시킬 수 있다.

인터페이스 일관성 Uniform Interface

  • 인터페이스 일관성은 다음과 같은 4가지 원칙으로 확장된다.
    • Resource-Based
    • Manipulation of Resources Through Representations
    • Self-descriptive Messages
    • Hypermedia as the Engine of Application State (HATEOAS)
  • 그는 많은 REST가 Self-descriptive Messages와 HATEOAS를 지키지 않고 있다고 주장하며 “이것은 REST가 아니다”라는 말을 남겼다. 심지어 마이크로소프트가 만든 Microsoft REST API Guidelines 마저 REST가 아니라고 하였다.

Self-descriptive Messages

  • 스스로를 설명할 수 있어야 한다.
  • html : <h2>타이틀</h2>
    • 위의 코드 중 h2 태그는 웹개발을 접한 모두가 무엇을 의미하는지 알고 있다.
    • 우리는 어떻게 h2가 무엇인지 이해하는가? 태그를 설명하는 명세서가 존재하기 때문이다. IANA, W3C에 text/html에 대한 명세가 존재하며 h2가 무엇인지를 설명한다.
  • json : {"id":"kim","age":13}
    • 위의 코드는 누구나 이해할 수 없다.
    • id와 age는 직관적으로 이해할 수 있지만 정확하게 무엇을 의미하는지 우리는 알 수가 없다.

HATEOAS

  • With HATEOAS, a client interacts with a network application whose application servers provide information dynamically through hypermedia. A REST client needs little to no prior knowledge about how to interact with an application or server beyond a generic understanding of hypermedia.
  • 위키백과에 따르면 헤이티오스가 적용된 어플리케이션의 특징은 다음과 같다 : 클라이언트는 하이퍼미디어를 통하여 어플리케이션과 상호작용한다. 기반지식이 없더라도 누구나 사용 가능하다.
  • html : <a href="/myinfo/{id}">내 정보 보기</a>
    • html에 대한 어떤 지식이 없더라도 우리는 브라우저에 렌더링된 페이지에서 a 태그를 클릭하여 내 정보를 볼 수 있다.
  • json : {"id":"kim","age":13}
    • 그저 정보 덩어리만 전달되었다. 어떤 상호작용도 불가능하다.

이것은 REST가 되기 위해서

  • 아이러니하게 html은 Self-descriptive Messages와 HATEOAS를 잘 지키는 REST 아키텍쳐였다.
  • 일반적으로 REST API를 설계함에 있어서 필수요소라 생각했던,
    • path parameter를 활용하는 url 규칙이나
    • get/post/put/delete 등 매서드의 적극적 활용이나
    • status code를 적극적으로 활용하는 것은
    • REST의 일부분만을 충족시켰다.
  • REST의 원칙을 지키기 위해서는 무엇을 해야할까? 스프링을 기반으로 구현한다면 아래의 방식을 활용할 수 있다.

Spring HATEOAS

  • 스프링은 HATEOAS 구현을 위한 프레임워크를 제공한다.
  • 구체적인 내용은 다음 문서를 참고하자 : https://spring.io/guides/gs/rest-hateoas/

OpenApi3.0, Rest Docs

  • 일반적으로 Self-descriptive Messages를 위한 명세서를 만들 때 OpenApi3.0와 Rest Docs를 주로 사용한다. 스프링에서는 의존성으로 쉽게 구현 가능하며 해당 문서는 아래와 같다.
    • Rest Docs : https://spring.io/guides/gs/testing-restdocs/
    • OpenApi 3.0 : https://www.baeldung.com/spring-rest-openapi-documentation
    • OpenApi는 Swagger의 새로운 이름으로서, 공개된 api를 의미하는 open api와 다르다.
  • 미디어타입(content-type)을 정의하고 해당 타입에 대한 명세를 공개할 수 있다.
    • Content-Type: application/infoqoch.production+json
    • infoqoch.production+json 타입을 정의할 수 있다.
  • 내가 정의한 타입을 text/html처럼 IANA 등 공식문서로 등록한다면 좋겠지만, Link 헤더를 사용하여 해당 명세를 볼 수 있는 링크를 제공할 수도 있다.
    • Link: <https://example.com/docs/production>; rel="profile"