모르지 않다는 것은 아는것과 다르다.

Network

REST API란

채마스 2022. 2. 27. 01:06

API 란?

  • Application Programming Interface
  • API는 프로그램들이 서로 상호작용하는 것을 도와주는 매개체로 볼 수 있다.
  • API의 역할
    • API는 서버와 데이터베이스에 대한 출입구 역할을 한다.
    • API는 애플리케이션과 기기가 원활하게 통신할 수 있도록 한다.
    • API는 모든 접속을 표준화한다.





REST 란?

  • REpresentational State Transfer
  • 컴퓨터 시스템와 인터넷 사이에 상호 운용성을 제공하는 방법중 하나이다.
  • 시스템 제각각의 독립적인 진화를 보장하기 위한 방법이다.
  • REST API: REST 아키텍처 스타일을 따르는 API 를 뜻한다.





REST를 구성하는 스타일

  • Client-Server : 클라이언트 - 서버 구조를 이루어야 한다.
  • Stateless : 상태가 유지되어선 안되고, 단순히 데이터를 주고받는 것으로 끝나야한다.
  • Cache : 클라이언트는 응답을 캐싱할 수 있어야 한다.
  • Uniform Interface : 아래에서 자세히 설명하겠다.
  • Layered System : 계층형 구조가 되어야 한다.
  • Code-on-Demand (optional) : 서버에서 코드를 클라이언트로 보내서 실행할 수 있어야 한다
  • REST API 라고 부르는 API 들은 대체로 위의 조건을 거의 만족하고 있다.
    • 그 이유는 HTTP만 잘 따라도 Client-Server, Stateless, Cache, Layered System은 다 지킬 수 있기 때문이다.
    • Code-on-Demand는 서버에서 코드를 클라이언트로 보내서 실행할 수 있어야 한다는 것을 의미, 즉 자바스크립트를 의미하고 이는 필수는 아니다.
    • 그렇다면 로이 필딩는 왜 대부분의 REST API 라고 주장하는 API 들이 REST 스럽지 못하다고 했을까?
      • 그 이유는 Uniform Interface를 만족하지 못하는 것이 대부분이다.





Uniform Interface 제약 조건

  • Identification of resources
    • URI로 리소스가 식별되면 된다는 것
  • Manipulation of resources through representations
    • Manipulation of resources through representations는 representation 전송을 통해서 리소스를 조작해야된댜는 것
  • Self-descriptive messages
    • 메시지는 스스로를 설명해야한다.
  • Hypermedia as the engine of application state(HATEOAS)
    • 애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다.
  • 여기서 Identification of resources, Manipulation of resources through representations 의 조건이 갖는 의미는 리소스를 만들거나 삭제, 수정할 때 http 메시지에 그 표현을 전송해야된다는 것이다. 이 2가지 조건은 대부분 잘 지켜지고 있다.
  • 하지만 Self-descriptive messages, ypermedia as the engine of application state 는 사실 우리가 REST API라고 부르는 거의 모든 것들은 지키지 못하고 있다.





Self-descriptive messages

  • 메시지 스스로 메시지에 대한 설명이 가능해야 한다.
  • 서버가 변해서 메시지가 변해도 클라이언트는 그 메시지를 보고 해석이 가능하다.
  • 확장 가능한 커뮤니케이션을 말한다.
  • 미디어 타입을 정의하고 IANA에 등록하고 그 미디어 타입을 리소스 리턴할 때 Content-Type으로 사용하면 해결할 수 있다.
  • 예시
    • Self-descriptive messages를 만족하지 못한 예시
      GET / HTTp/1.1
      • 목적지가 빠져있다.
        HTTP/1.1 200 OK
        [ { "op": "remove", "path": "/a/b/c" } ]
      • 클라이언트가 해석하지 못한다.
    • Self-descriptive messages를 만족한 예시
      GET / HTTp/1.1
      Host: www.example.org
      • 목적지를 정의했기에 만족한다.
        HTTP/1.1 200 OK
        Content-Type: application/json-patch+json
        [ { "op": "remove", "path": "/a/b/c" } ]
      • json-patch+json이라는 미디어 타입으로 정의된 메시지이기 때문에 json-patch라는 명세를 찾아가서 이해한 다음, 이 메시지를 해석을 하면 그제서야 올바르게 메시지의 의미를 이해할 수 있게 된다.
  • profile 링크 헤더를 추가하는 방법으로 아래와 같이 해결할 수도 있다.
    • 이제 메시지를 보는 사람은 명세를 찾아갈 수 있음 → 의미 해석 가능
  • GET /todos HTTP/1.1 Host: example.org HTTP/1.1 200 OK Content-Type: application/json Link: <https://exmaple.org/docs/todos>; rel="profile" [ {"id": 1, "title": "회사 가기"}, {"id": 2, "title": "집에 가기"} ]






Hypermedia as the engine of application state(HATEOAS)

  • 하이퍼미디어(링크)를 통해 애플리케이션 상태 변화가 가능해야 한다.
  • 링크 정보를 동적으로 바꿀 수 있다.
  • 즉, 애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다.

  • 상태는 아래와 같이 변할 수 있다.
    루트 홈페이지 → 글 목록 보기 GET → 글 쓰기 GET → 글 저장 POST → 생성된 글 보기 GET → 목록 보기 GET →
  • 이렇게 상태를 전이하는 것을 애플리케이션 상태 전이라고 하고, 이 상태 전이마다 항상 해당 페이지에 있던 링크를 따라가면서 전이했기 때문에 HATEOAS라고 할 수 있다.
  • 그렇다면 왜 REST 가 지켜지기 어려운가?

  • 위에서 보듯 의미를 해석하기 위해서는 별도의 문서가 필요하다.
    HTTP/1.1 200 OK
    Content-Type: text/html
    

test

``` - a 태그를 통해서 하이퍼링크가 나와 있고, 이 하이퍼 링크를 통해서 그 다음 상태로 전이가 가능하기 때문에 만족한다고 볼 수 있다.

  • Json으로 표현하면 아래와 같다.
    HTTP/1.1 200 OK
    Content-Type: application/json
    Link: </articles/1>; rel="previous",
              </articles/3>; rel="next";
    

{
"title": "The second article",
"contents": "blah blah..."
}

- Link라는 헤더가 있는데, 이것이 바로 이 리소스와 하이퍼링크로 연결되어 있는 다른 리소스를 가르킬 수 있는 기능을 제공해준다.
- 여기서 어떤 1개의 게시물을 표현 했는데, 이전의 게시물 URI가 /articles/1, 다음 게시물은 /articles/3에 있다는 정보를 표현해준 것이다.
- 이 정보는 Link 헤더가 이미 표준으로 문서가 나와 있기 때문에 이 메시지를 보낸 사람이 온전히 해석해서 어떻게 링크가 되어 있는가를 이해하고 하이퍼링크를 타고 다른 상태로 전이가 가능하다.
- 또한 아래와 같이 JSON으로 하이퍼링크를 표현하는 방법을 정의한 명세들을 활용해서 해결할 수 있다.

```java
GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
Link: <https://exmaple.org/docs/todos>; rel="profile"

{
    "data": [{
        "type": "todo",
        "id": 1, 
        "attributes": {"title": "회사 가기"},
    "links" : { "self": "https://example.org/todos/1"
    },{
        "type": "todo",
        "id": 2, 
        "attributes": {"title": "집에 가기"},
    "links" : { "self": "https://example.org/todos/2"
    }]
}



정리

  • 오늘날 대부분 "REST API"는 사실 REST를 따르고 있지 않다.
  • REST의 제약 조건 중 특히 self-descriptive와 HATEOAS를 잘 만족하지 못한다.
  • REST를 따를 것인지는 API 설계하는 이들이 스스로 판단하여 결정하면 되지만, REST의 조건을 전부 만족시킬 수 없다면 REST API라 부를 수 없다.




REFERENCES

'Network' 카테고리의 다른 글

쿠키와 캐시  (0) 2022.02.27
네트워크  (0) 2022.02.27
URI 설계 원칙(RFC-3986)  (0) 2022.02.27
HTTP  (0) 2022.02.27