프로젝트에서 경험한 사례로 REST API 의 조건인 HATEOAS에 대해 알아보겠습니다.
HATEOAS란
먼저 REST API는 6가지 주요 제약 조건을 가지고 있습니다.
- 클라이언트 서버 아키텍쳐
- STATELESS
- 캐시 가능성
- 계층화된 시스템
- 코드 온디맨드(옵션)
- 균일한 인터페이스(uniform interface)
그 중에서 균일한 인터페이스라는 조건은 서버와 통신하는 단일 방법이 있음을 나타내는 것으로, RESTful API의 핵심이고 4가지 측면을 갖고 있습니다. 그 중에 하나가 애플리케이션 상태 엔진으로서의 하이퍼미디어 라는 것입니다.
다시 말하면, 리소스를 할당한 후 REST 클라이언트가 하이퍼링크를 통해 현재 사용 가능한 다른 모든 작업을 찾을 수 있어야 하는 것입니다.
예를 들면, 주문 정보를 가져오는 리소스에서 연관 상태인 상품 정보를 확인하고 싶을 때 하이퍼링크를 통해 찾을 수 있는 것입니다.
HATEOAS를 지키지 않은 응답 예시
수행한 프로젝트의 응답을 예시로 들어보겠습니다.
푸쉬 알림 리스트를 보여주는 응답 JSON으로, 페이스북의 게시물 목록과 비슷한 형태입니다. 내용이 있고 그 내용에 해당하는 리액션을 보여줍니다. notifications 안에 reactions 리소스 부분입니다.
응답 내용에 reactions.reaction_count_infos를 보면 해당 게시물에 대한 리액션 정보가 아닌 reaction_id, reaction_url 정보같은 공통적으로 사용하는 리액션의 정보도 포함되어 있습니다.
바로 이 부분을 하이퍼링크로 제공해주어야 리소스의 사용 가능한 다른 작업을 찾을 수 있도록 서버와 통신하는 균일하고 일관된 인터페이스를 제공해주게 됩니다.
HATEOAS를 만족하는 API 응답이 됩니다.
HATEOAS를 만족하는 응답 예시
github이 제공하는 api가 HATEOAS를 잘 지킨 대표적 사례입니다.
Github의 피드 목록를 가져오는 Get feeds API 응답은 아래와 같습니다.
links를 통해 연관된 상태를 가져올 수 있는 하이퍼링크를 제공합니다.
기존 수행 했던 프로젝트의 응답 형태였던 위 [그림1]에서 HATEOAS를 만족하는 형태로 응답형태를 바꾸면 아래와 같이 될 수 있습니다.
HATEOAS를 지켰을 때 장점
위 [그림1]처럼 HATEOAS를 만족하지 않게 응답을 제공했을 때 서버에서는 연관 상태를 매번 조회하고 응답을 보내줘야 합니다. 연관 상태가 필요없을 때는 불필요한 작업을 하게 될 수 있습니다.
대안으로 클라이언트에게 groups 이나 reactions 정보를 가져올 수 있는 uri를 전해주고 클라이언트 코드에서 연관상태를 호출하는 방법도 있습니다. 이 방법은 클라이언트 코드에 연관 상태 uri를 하드코딩해야 하므로 리소스 uri가 변경되었을 때 클라이언트 코드도 수정되어야 하므로 좋지 않는 방법입니다.
그리고 가장 큰 문제는 서버와 클라이언트의 통신에서 규약을 지키지 않은 사례가 됩니다. 리소스의 다른 작업을 찾을 때 하이퍼링크로 제공해준다는 원칙을 지키지 않아 별도로 문서로 남기거나 클라이언트 코드에 불필요한 코드를 작성하게 됩니다.
HATEOAS를 지키면 서버와 클라이언트에서 발생할 수 있는 위 두가지 문제를 해결할 수 있습니다.
Spring HATEOAS
스프링에서는 HATEOAS 원칙을 따르는 REST API를 만들기 위해 Spring HATEOAS를 제공하고 있습니다.
결론
REST 한 API에 대해서 알아보면서 프로젝트에 적용할 수 있는 HATEOAS개념에 대해 알아보았습니다. 적용하지 않았더라도 프로젝트 구현 시 서버가 부담을 가져갈 것인지 아니면 클라이언트 코드에 하드코딩 된 uri를 제공함으로써 변경에 유연하지는 않는 부분을 선택할지 협의할 수 있는 부분에 대해 알아보았습니다.
매번 연관 상태를 표현해줘야 한다면 서버에서 조회해 응답 보내주는 것도 좋은 방법이 될 수 있고, 그렇지 않을 경우 클라이언트에서 해결하는 방법도 선택할 수 있을 것 같습니다.
하지만 REST API의 HATEOAS를 알아보면서 별도의 히스토리를 남겨야 하는 규약을 위반하는 규약은 사용하지 않는게 좋을 것 같다는 것이 개인적 의견입니다.
참고자료
- SOAP, WEB API, REST API 차이 : https://www.redhat.com/ko/topics/api/what-are-application-programming-interfaces
- REST API 모범 사례 – REST 엔드포인트 설계 예시 : https://www.freecodecamp.org/korean/news/rest-api-mobeom-sarye-rest-endeupointeu-seolgye-yesi/
댓글