본문 바로가기

개발중/Rest Api

[ Rest API ] HATEOAS 를 써야 할까 ?

728x90
반응형

HATEOAS 를 써야 할까 ?

 

REST라는 용어는 많은 소프트웨어 용어와 같이 다양한 정의가 있다.

로이 필딩이 이것을 만들었기 때문에 그의 정의는 다른 사람들의 정의보다 더 많은 가치를 지녀야 한다.

 

하지만 RESTful 을 충족하는 것이 신성한 것으로 간주돼서는 안되며

레벨 2의 서비스가 되는 것이 해당 API 가 레벨 3 의 API 보다 열등하다는 것을 의미하지 않는다.

 

HATEOAS 를 구현할지 말지는 API 의 본질과 노력의 가치 여부에 달려있다.


HATEOAS 란 무엇일까 ?

 

다음과 같은 예가 있다.

 

POST https://api.examplebuks.org/orders HRRP/1.1

Content-Type : application/json

Content-Length : 33

 

{"drink":"latte", "quantity":1}

 

이것은 라떼 한 잔을 주문하기 위해 전송한 POST 요청이다.

응답으로는 서버는 다음 코드에서 보다시피 틀라이언트가 다음에 수행할 수 있는 것에 대한 정보를 제공 한다.

 

{

    "id"         :  971103

    "drink"     : "latte",

    "quantity" : 1,

    "cost"       : 1,

    "status"     : "pending",

    "_links"     : {

        "self" : {

                "href" : "https://api.examplebuks.org/orders/971103"

                "type" : "GET"

        },

        "payment" : {

                "href" : "https://api.examplebuks.org/payments/971103"

                "type" : "PUT"

        },

        "update" : {

                "href" : "https://api.examplebuks.org/orders/971103"

                "type" : "PUT"

        },

        "cancel" : {

                "href" : "https://api.examplebuks.org/orders/971103"

                "type" : "DELETE"

        }

    } 

}

 

보다시피 응답에서 HAL (Hypertext Application Language) 규약을 따르는

하이퍼텍스트인 _links 프로퍼티는 클라이언트가 수행할 수 있는 작업을 포함한다.

 

_links 객체에서 관계에 대한 각 키의 표준과 해당 관계의 HREF 프로퍼티는 리소스의 URL 이지만

Type 프로퍼티는 해당 리소스에 대해 수행되야 하는 HTTP 메소드 이다.

 

하이퍼 텍스트는 보통 지정된 리소스에 허용되는 모든 작업을 알려주지 않는다.

그것은 잠재적인 전환에 사용할 작업을 알려준다.

클라이언트가 어떤 인터페이스를 활용할지가 아니라, 어떤 전환을 취해야 할지 결정해야 한다.

 

따라서 클라이언트가 주문서를 업데이트 한다면 _links 하이퍼 텍스트를 통해 update 작업을 찾을 수 있고

클라이언트가 주문을 취소해야 한다면 해당 _links 하이퍼 텍스트에서 cancel 작업을 찾을 수 있다.

 

또한 하이퍼텍스트는 클라이언트를 리소스의 URL으로 부터 분리하기 때문에

API 개발자는 _links 하이퍼텍스트로 클라이언트가 깨지지 않은 상태에서 리소스의 URL 을 변경할 수 있다.

 

클라이언트는 더는 URL 을 하드코딩 할 필요가 없으며

그들이 이해해야 하는 것은 _links 하이퍼텍스트에 반환된 각 작업의 의미다.

 

API 의 클라이언트를 제어할 수 없는 경우에 이것이 중요하다.

 

예를 들어 트위터와 같은 공개적으로 이용할 수 있는 API 를 구축할 때 대부분의 클라이언트를 제어할 수 없다.

또한 리소스 URL 의 리소스의 오타를 수정하고 싶을 때 공개적인 서비스를 중단 할 일도 없어진다.

 

HATEOAS 의 옹호자에 따르면

또 다른 이점은 API 를 보다 자기 서술적으로 만들고 고객이 자주 그 문서를 살펴보지 않아도 된다는 것이다.

RESTful API 를 탐색하기 위해 API 응답에서 하이퍼텍스트를 간단하게 확인해 API 를 검색할 수 있게 만들 수 있다.

 

이것이 HATEOAS 의 기본 개념이다.


왜 HATEOAS 가 필요 없다고 생각하는가 ?

 

실제로는 보통 HATEOAS 가 필요 없다고 생각한다. 이유는 다음과 같다.

 

첫번째

우선 HATEOAS 를 구현하고 유지 관리를 하려면 서버와 클라이언트 모두 노력이 필요하다.

서버 측면에서는 리소스의 상태를 기반으로 하이퍼텍스트를 구성해야 하며,

클라이언트는 올바른 작업을 수행해 하이퍼텍스트의 의미를 분석하고 이해해야 한다.

 

HATEOAS를 충족하지 않는 API 와 비교해 클라이언트 측에서 해야 할 일은

리소스의 URL 을 하드코딩하고 리소스의 표현에 따라 사용 가능한 작업을 결정하는 것이다.

 

예를 들어 커피 주문 예제에서 status 필드의 값을 기반으로

계산서 만들기, 주문 업데이트 하기, 주문 취소하기 중 이용 가능한 작업을 찾을 수 있다.

 

이렇게 하여 HATEOAS를 충족시켜 서버 측면의 오버헤드와 클라이언트 측의 하이퍼 텍스트의 분석을 피할 수 있다.

 

두번째

HATEOAS를 채택함으로써 리소스의 URL 와 클라이언트를 분리하는 것에 대한 이점이 확실하지 않다.

해당 클라이언트는 수행해야 할 작업을 확인하기 위해 하이퍼텍스트의 의미를 여전히 알아야 한다.

 

예를 들어 주문을 업데이트 하기 위한 이전 예제 표준에서

update 작업에 클라이언트와 하이퍼텍스트 간의 결합이 여전히 존재한다.

 

클라이언트 측면에서 _links.update 는 해당 작업을 위한 URL 의 위치를 찾는데 할용된다.

그것은 _links.edit 와 _links.modify 둘 다 아니다.

이 update 작업은 간단한 예제이고 일반적인 표현이다.

 

특정 작업을 수행하기 위한 고유한 표현을 사용하는 애플리케이션의 경우

클라이언트는 그 표현과 연동이 필요하다.

그리고 그 표현들은 url 와 유사하게 변경 될 수 있다.

 

유일한 차이점은 URL 이 빈번하게 변경되지 않을 수도 있다는 것이다.

하지만 그렇다고 해서 HATEOAS 가 클라이언트에 영향을 주지도 않고 독립적으로 API 를 발전 시킨다는 의미는 아니다.

사용하는 표현이 확장 가능한지 확인하는데 여전히 많은 노력을 기울어야 한다.

대부분의 시간을 API 를 변경하는데 사용하는 것이 불가피 하므로

이러한 변경 사항을 관리하기 위한 API 변경 전략을 수립해야 한다.

이것이 바로 페이팔의 API 가 버전관리를 포함하는 이유다.

 

세번째

API 의 응답을 통해 하이퍼 텍스트가 제공하는 API 의 자기서술은 전체가 아닌 일부다.

즉 여전히 하이퍼텍스트에 나열된 해당 작업에 대한 모든 정보를 찾으려면 다음 정보를 활용해야 한다.

예를 들어 계산서 만들기와 주문 업데이트 하기와 같은 작업에서

그러한 정보는 하이퍼텍스트에 드러나지 않기 때문에 해당 API 가 허용하는 입력 매개변수가 무엇인지

서버로 전송할 표현을 알아야 한다.

 

따라서 API 클라이언트 개발자의 경우 이처럼 API 를 활용하기 어렵고

개발자에게 친화적이지 않은 API 조각들을 모두 넣어 확인해야 한다.

 

좀 더 개발자 친화적인 방법은 개발자가 해당 API 에 대해 알아야 할 모든 정보를 제공하는 API 문서를 가지는 것이다.


 

728x90
반응형