본문 바로가기
Concept/REST API

[REST API]프로젝트에서 경험한 API 설계 - HATEOAS

by devstep 2023. 4. 4.

프로젝트에서 경험한 사례로 REST API 의 조건인 HATEOAS에 대해 알아보겠습니다. 

 

HATEOAS란

먼저 REST API는 6가지 주요 제약 조건을 가지고 있습니다. 

  1.  클라이언트 서버 아키텍쳐
  2. STATELESS
  3. 캐시 가능성
  4. 계층화된 시스템
  5. 코드 온디맨드(옵션)
  6. 균일한 인터페이스(uniform interface)

그 중에서 균일한 인터페이스라는 조건은 서버와 통신하는 단일 방법이 있음을 나타내는 것으로, RESTful API의 핵심이고 4가지 측면을 갖고 있습니다. 그 중에 하나가 애플리케이션 상태 엔진으로서의 하이퍼미디어 라는 것입니다.
다시 말하면, 리소스를 할당한 후 REST 클라이언트가 하이퍼링크를 통해 현재 사용 가능한 다른 모든 작업을 찾을 수 있어야 하는 것입니다. 

예를 들면, 주문 정보를 가져오는 리소스에서 연관 상태인 상품 정보를 확인하고 싶을 때 하이퍼링크를 통해 찾을 수 있는 것입니다. 

 

HATEOAS를 지키지 않은 응답 예시

수행한 프로젝트의 응답을 예시로 들어보겠습니다.

푸쉬 알림 리스트를 보여주는 응답 JSON으로,  페이스북의 게시물 목록과 비슷한 형태입니다. 내용이 있고 그 내용에 해당하는 리액션을 보여줍니다. notifications 안에 reactions 리소스 부분입니다.

응답 내용에 reactions.reaction_count_infos를 보면 해당 게시물에 대한 리액션 정보가 아닌 reaction_id, reaction_url 정보같은 공통적으로 사용하는 리액션의 정보도 포함되어 있습니다. 

바로 이 부분을 하이퍼링크로 제공해주어야 리소스의 사용 가능한 다른 작업을 찾을 수 있도록 서버와 통신하는 균일하고 일관된 인터페이스를 제공해주게 됩니다.

HATEOAS를 만족하는 API 응답이 됩니다. 

[그림1] HATEOAS를 만족하지 않는 API 응답 형태

 

HATEOAS를 만족하는 응답 예시

github이 제공하는 api가 HATEOAS를 잘 지킨 대표적 사례입니다.

Github의 피드 목록를 가져오는 Get feeds API 응답은 아래와 같습니다.
links를 통해 연관된 상태를 가져올 수 있는 하이퍼링크를 제공합니다.  

 

기존 수행 했던 프로젝트의 응답 형태였던 위 [그림1]에서 HATEOAS를 만족하는 형태로 응답형태를 바꾸면 아래와 같이 될 수 있습니다. 

HATEOAS를 만족한 상태

 

HATEOAS를 지켰을 때 장점

위 [그림1]처럼 HATEOAS를 만족하지 않게 응답을 제공했을 때 서버에서는 연관 상태를 매번 조회하고 응답을 보내줘야 합니다. 연관 상태가 필요없을 때는 불필요한 작업을 하게 될 수 있습니다. 

대안으로 클라이언트에게 groups 이나 reactions 정보를 가져올 수 있는 uri를 전해주고 클라이언트 코드에서 연관상태를 호출하는 방법도 있습니다. 이 방법은 클라이언트 코드에 연관 상태 uri를 하드코딩해야 하므로 리소스 uri가 변경되었을 때 클라이언트 코드도 수정되어야 하므로 좋지 않는 방법입니다.
그리고 가장 큰 문제는 서버와 클라이언트의 통신에서 규약을 지키지 않은 사례가 됩니다. 리소스의 다른 작업을 찾을 때  하이퍼링크로 제공해준다는 원칙을 지키지 않아 별도로 문서로 남기거나 클라이언트 코드에 불필요한 코드를 작성하게 됩니다.  

HATEOAS를 지키면 서버와 클라이언트에서 발생할 수 있는 위 두가지 문제를 해결할 수 있습니다. 

 

Spring HATEOAS

스프링에서는 HATEOAS 원칙을 따르는 REST API를 만들기 위해 Spring HATEOAS를 제공하고 있습니다.

 

결론

REST 한 API에 대해서 알아보면서 프로젝트에 적용할 수 있는 HATEOAS개념에 대해 알아보았습니다. 적용하지 않았더라도 프로젝트 구현 시 서버가 부담을 가져갈 것인지 아니면 클라이언트 코드에 하드코딩 된 uri를 제공함으로써 변경에 유연하지는 않는 부분을 선택할지 협의할 수 있는 부분에 대해 알아보았습니다. 

매번 연관 상태를 표현해줘야 한다면 서버에서 조회해 응답 보내주는 것도 좋은 방법이 될 수 있고, 그렇지 않을 경우 클라이언트에서 해결하는 방법도 선택할 수 있을 것 같습니다. 
하지만 REST API의 HATEOAS를 알아보면서 별도의 히스토리를 남겨야 하는 규약을 위반하는 규약은 사용하지 않는게 좋을 것 같다는 것이 개인적 의견입니다. 

 

 


참고자료

 

 

댓글