Uniform Interface 의 제약조건
- identification of resources
- 각각의 정보 자원(RESOURCE) 이 고유한 식별자(IDENTIFIER) 를 통해 구별되고 접근이 가능해야한다는 원칙
- 클라이언트는 URI 를 통하여 자원에 접근 , 상호작용
- 각각의 정보 자원(RESOURCE) 이 고유한 식별자(IDENTIFIER) 를 통해 구별되고 접근이 가능해야한다는 원칙
- manipulation of resources through representations
- 클라이언트가 서버에 있는 자원(RESOURCE) 을 조작 (MANIPULATE) 할때 , 해당 자원의
표현(representation)
을 통해 이루어져야 한다.- 표현이란?
- 자원의 상태를 나타내는 형식화된 데이터
- JSON 혹은 XML 을 의미함.
- 자원의 상태를 나타내는 형식화된 데이터
- 표현이란?
- 클라이언트가 서버에 있는 자원(RESOURCE) 을 조작 (MANIPULATE) 할때 , 해당 자원의
위 2가지는 보통의 REST API 에서 일반적으로 지켜지고 있는 개념이다.
하지만 아래의 경우는 잘 지켜지지 않는다고 한다.
self-descriptive messages
- 메시지가 스스로를 설명할 수 있어야 한다!.
- 메세지를 받는 쪽에서 별도의 문서나 외부 정보 없이도 메시지를 이해할 수 있고
- 처리할 수 있어야 한다는 말입니다.
- 예를 들어
- HTTP 응답에
Content-Type
헤더가 포함되어 있어서- 해당 응답이 JSON 인지, HTML 형식인지 등을 명시하는 것이 해당 원칙의 사소한 예시입니다.
- 서버는 해당 헤더를 통해 어떻게 해당 응답 데이터를 파싱하고 처리하는지 알 수가 있습니다.
- HTTP 응답에
- 메세지를 받는 쪽에서 별도의 문서나 외부 정보 없이도 메시지를 이해할 수 있고
hypermedia as the engine of application state (HATEOAS)
- 클라이언트가 서버와의 상호작용을 하는 경우
- 해당 상호작용이 가능한 다음 상태를 알려주는 하이퍼미디어 링크를 통하여 이루어져야 한다.
- 예를들어
- 웹 API를 통해 특정 상품의 정보를 조회시, 응답으로 받은 데이터에는
- 그 상품을 장바구니에 추가
- 리뷰를 남기기
- 관련 상품 보기
- 등의 다음 가능한 액션에 대한 링크가 포함이 되어 있어야 한다.
- 이를 통하여 서버의 API 문서를 참조하지 않고 동적으로 애플리케이션을 탐색 * 사용이 가능함
- 웹 API를 통해 특정 상품의 정보를 조회시, 응답으로 받은 데이터에는
클라이언트와 서버는 독립적으로 진화한다.
- 클라이언트와 서버가 각각 변경 사항을 서로에게 강제X , 상호 호환성을 유지하면서 발전할 수 있어야 한다고 합니다.
- 이를 정확하게 지킬 수 있는 것이 바로..
Self descriptive messages , HATEOAS 입니다.
- 클라이언트가 서버의 구현 세부사항을 알 필요 없이 통신 가능하고,
- 서버의 변경으로 클라이언트에 영향을 주지 않도록 할 수 있다.
- 서버가 새로운 기능을 추가하거나
- API 를 변경하더라도, HATEOAS 원칙에 따라 제공되는 하이퍼미디어 링크를 통해 클라이언트는 이런 변경점을 감지하고 적응가능함
부득이하게 영상 스크린샷
- 위 2개의 사진만 봐도
- HTML 의 경우 href 링크를 통해 다음 행동이 어디로 이어질 지에 대한 경우의 수를 체킹이 가능하다
- 하지만
- JSON 의 경우 키-밸류 값만으론 그 다음 어떤 행동이 이어지는 건지 도저히 알 수가 없을 뿐만아니라, 다음 상태로의 전이 링크가 없음
Self-Descriptive 한 해결방안
- Media-Type 의 선언
Content-Type : application/vnd.todos+json
과 같은 미디어 타입을 하나 정의후
미디어 타입에 JSON 에서 응답으로 받아온, id 와 title 의 의미를 정의함
정의는 IANA 에 한다.
- IANA??
- 인터넷에서 사용되는 여러 종류의 번호 자원을 관리하는 기관.
- IP 주소, 도메인 이름, 프로토콜 파라미터 , 포트번호 등이 포함되어 있음.
하지만, 미디어 타입 정의마다 사이트에 들어가서 정의하는건 매우 번거롭다.
말도 안됨.
- IANA??
- profile
Link: <https://example.org/docs/todos>; rel="profile"
- Link 헤더에
profile relation
으로 해당 명세 링크함- profile relation?
- rel = “profile” 으로서 링크와의 관계성 정의부분
- profile relation?
다만, 클라이언트가 Link 헤더 (RFC 5988) 과 profile(RFC 6906) 에 대한 이해가 필요하며,
Content negotiation 이 불가능하다고함
- Content negotiation?
- 클라이언트가 웹 페이지를 요청하는 경우
- HTML , JSON , XML 등 다양한 형식 중 어떤 형식을 선호하는지 HTTP 요청 헤더를 통하여..
- Accept … Accept-Encoding … 선호 미디어 타입 ,선호 인코딩.. 을 말함
- 서버에 전달함.
- 서버는 해당 정보를 확인하고, 사용 가능한 형식 중 하나를 선택하여 해당 형식으로 데이터를 구성하여 응답함.
- HTML , JSON , XML 등 다양한 형식 중 어떤 형식을 선호하는지 HTTP 요청 헤더를 통하여..
- 클라이언트가 웹 페이지를 요청하는 경우
- 위 profile 은 콘텐츠 형식, 언어, 인코딩을 결정하는 것이 아니라,
- 단순히 규칙이나 약속을 지키는지를 설명하기 위한 지침서일 뿐이기 때문에, 협상의 대상이 안됨
- Link 헤더에
HATEOAS 한 해결방안
- data 로 해결
- 응답 데이터안에 링크를 넣는 방식
- 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"
- Link 헤더를 사용합니다
Media Type 의 등록은 필수?
- 아님.
총평
- RESTful 하게 API 를 개발한다?
- 이건 사실 회사 입장에서는 불가능 행위라고 생각한다.
- 사실 기능 개발과 테스트코드에만 힘을 쏟아도 빡빡한데
- HATEOAS 와 self-descriptive 하게 개발을 시도하는 순간
- 사실상 학자만이 가능한 개발 포지션이 되어 버릴 것 같다.
- 다만, REST API 라고 칭하는 것을 개발하는 개발자로서, 적어도 어떤 의도에서 등장했으며, 어떤 것인지는 알아야 한다고 생각한다.
적어도 이정도의 REST함은 유지하자! 라고 등장한게
- 스웨거와 Spring RestDocs 이다!
Uploaded by N2T