[D2] 그런 REST API 로 괜찮은가 .. 에 대한 정리

Uniform Interface 의 제약조건

  1. identification of resources
    1. 각각의 정보 자원(RESOURCE) 이 고유한 식별자(IDENTIFIER) 를 통해 구별되고 접근이 가능해야한다는 원칙
      1. 클라이언트는 URI 를 통하여 자원에 접근 , 상호작용
  1. manipulation of resources through representations
    1. 클라이언트가 서버에 있는 자원(RESOURCE) 을 조작 (MANIPULATE) 할때 , 해당 자원의 표현(representation) 을 통해 이루어져야 한다.
      1. 표현이란?
        1. 자원의 상태를 나타내는 형식화된 데이터
          1. JSON 혹은 XML 을 의미함.

위 2가지는 보통의 REST API 에서 일반적으로 지켜지고 있는 개념이다.

하지만 아래의 경우는 잘 지켜지지 않는다고 한다.

self-descriptive messages

  1. 메시지가 스스로를 설명할 수 있어야 한다!.
    1. 메세지를 받는 쪽에서 별도의 문서나 외부 정보 없이도 메시지를 이해할 수 있고
      1. 처리할 수 있어야 한다는 말입니다.
    1. 예를 들어
      1. HTTP 응답에
        1. Content-Type 헤더가 포함되어 있어서
          1. 해당 응답이 JSON 인지, HTML 형식인지 등을 명시하는 것이 해당 원칙의 사소한 예시입니다.
          1. 서버는 해당 헤더를 통해 어떻게 해당 응답 데이터를 파싱하고 처리하는지 알 수가 있습니다.

hypermedia as the engine of application state (HATEOAS)

  • 클라이언트가 서버와의 상호작용을 하는 경우
    • 해당 상호작용이 가능한 다음 상태를 알려주는 하이퍼미디어 링크를 통하여 이루어져야 한다.
  • 예를들어
    • 웹 API를 통해 특정 상품의 정보를 조회시, 응답으로 받은 데이터에는
      1. 그 상품을 장바구니에 추가
      1. 리뷰를 남기기
      1. 관련 상품 보기
      • 등의 다음 가능한 액션에 대한 링크가 포함이 되어 있어야 한다.
      • 이를 통하여 서버의 API 문서를 참조하지 않고 동적으로 애플리케이션을 탐색 * 사용이 가능함

클라이언트와 서버는 독립적으로 진화한다.

  • 클라이언트와 서버가 각각 변경 사항을 서로에게 강제X , 상호 호환성을 유지하면서 발전할 수 있어야 한다고 합니다.
  • 이를 정확하게 지킬 수 있는 것이 바로..

    Self descriptive messages , HATEOAS 입니다.

    • 클라이언트가 서버의 구현 세부사항을 알 필요 없이 통신 가능하고,
    • 서버의 변경으로 클라이언트에 영향을 주지 않도록 할 수 있다.
      • 서버가 새로운 기능을 추가하거나
      • API 를 변경하더라도, HATEOAS 원칙에 따라 제공되는 하이퍼미디어 링크를 통해 클라이언트는 이런 변경점을 감지하고 적응가능함

부득이하게 영상 스크린샷

  • 위 2개의 사진만 봐도
    • HTML 의 경우 href 링크를 통해 다음 행동이 어디로 이어질 지에 대한 경우의 수를 체킹이 가능하다
    • 하지만
      • JSON 의 경우 키-밸류 값만으론 그 다음 어떤 행동이 이어지는 건지 도저히 알 수가 없을 뿐만아니라, 다음 상태로의 전이 링크가 없음

Self-Descriptive 한 해결방안

  1. Media-Type 의 선언
    Content-Type : application/vnd.todos+json

    과 같은 미디어 타입을 하나 정의후

    미디어 타입에 JSON 에서 응답으로 받아온, id 와 title 의 의미를 정의함

    정의는 IANA 에 한다.

    하지만, 미디어 타입 정의마다 사이트에 들어가서 정의하는건 매우 번거롭다.

    말도 안됨.

  1. profile
    Link: <https://example.org/docs/todos>; rel="profile"
    • Link 헤더에 profile relation 으로 해당 명세 링크함
      • profile relation?
        • rel = “profile” 으로서 링크와의 관계성 정의부분

    다만, 클라이언트가 Link 헤더 (RFC 5988) 과 profile(RFC 6906) 에 대한 이해가 필요하며,

    Content negotiation 이 불가능하다고함

    • Content negotiation?
      • 클라이언트가 웹 페이지를 요청하는 경우
        • HTML , JSON , XML 등 다양한 형식 중 어떤 형식을 선호하는지 HTTP 요청 헤더를 통하여..
          • Accept … Accept-Encoding … 선호 미디어 타입 ,선호 인코딩.. 을 말함
        • 서버에 전달함.
        • 서버는 해당 정보를 확인하고, 사용 가능한 형식 중 하나를 선택하여 해당 형식으로 데이터를 구성하여 응답함.
    • 위 profile 은 콘텐츠 형식, 언어, 인코딩을 결정하는 것이 아니라,
      • 단순히 규칙이나 약속을 지키는지를 설명하기 위한 지침서일 뿐이기 때문에, 협상의 대상이 안됨

HATEOAS 한 해결방안

  1. data 로 해결
    • 응답 데이터안에 링크를 넣는 방식
  1. HTTP 헤더에 포함
    • Link 헤더를 사용합니다

      클라이언트에게 관련된 리소스의 링크를 제공함으로,, 특정 리소스에 대한 GET 요청에 대한 응답으로 다음과 같은 LINK 헤더를 포함가능

      Link: <https://api.example.com/users/1>; rel="self",
      <https://api.example.com/users/1/friends>; rel="friends",
      <https://api.example.com/users/1/photos>; rel="photos"

Media Type 의 등록은 필수?

  • 아님.

총평

  • RESTful 하게 API 를 개발한다?
    • 이건 사실 회사 입장에서는 불가능 행위라고 생각한다.
  • 사실 기능 개발과 테스트코드에만 힘을 쏟아도 빡빡한데
    • HATEOAS 와 self-descriptive 하게 개발을 시도하는 순간
    • 사실상 학자만이 가능한 개발 포지션이 되어 버릴 것 같다.
  • 다만, REST API 라고 칭하는 것을 개발하는 개발자로서, 적어도 어떤 의도에서 등장했으며, 어떤 것인지는 알아야 한다고 생각한다.

    적어도 이정도의 REST함은 유지하자! 라고 등장한게

    1. 스웨거와 Spring RestDocs 이다!

Uploaded by N2T