API : 서로 다른 응용 프로그램간의 상호 작용 및 통신, 응용프로그램에서 데이터를 주고 받기 위한 방법

REST API

HTTP 프로토콜을 통해 API를 설계하기 위한 아키텍쳐 스타일.

REST(REpresentational State Transfer) 아키텍처 스타일의 디자인 원칙을 준수하는 API입니다. 이러한 이유로 REST API를 RESTful API라고도 합니다.

REST(Representational State Transfer)는 분산 시스템에서 자원을 표현하고 상태를 전송하기 위한 아키텍처 스타일입니다. REST는 주로 웹에서 사용되며, 웹 서비스의 기본 아키텍처로 널리 알려져 있습니다.

REST 구성 요소

자원(Resource) : URL

모든 자원에 고유한 ID가 존재하고, 이 자원은 Server에 존재한다.자원을 구별하는 ID는 ‘/groups/:group_id’와 같은 HTTP URL이다.Client는 URL를 이용해서 자원을 지정하고 해당 자원의 상태(정보)에 대한 조작을 Server에 요청한다.

행위(Verb) : HTTP Method

HTTP 프로토콜의 Method를 사용한다.HTTP 프로토콜은 GET, POST, PUT, DELETE와 같은 메서드를 제공한다.

표현(Representation of Resource)

Client가 자원의 상태(정보)에 대한 조작을 요청하면 Server는 이에 적절한 응답(Representation)을 보낸다.REST에서 하나의 자원은 JSON, XML, TEXT, RSS 등 여러 형태의 Representation으로 나타내어 질 수 있다.JSON 혹은 XML를 통해 데이터를 주고 받는 것이 일반적이다.

  • 높은 수준의 유연성과 자유를 제공

Untitled

REST 디자인 원칙 6가지

  • Client - Server 클라이언트 - 서버
    • 관심사 분리 (Separation of Concerns)
      • 사용자 인터페이스와 데이터 저장 관심을 분리하여 각각을 독립적으로 다룹니다.
      • 코드의 모듈성을 높이고, 변경이나 유지보수가 간편해지며, 이식성과 확장성을 향상시킵니다.
    • 서버의 독립적 진화
      • 클라이언트와 서버의 분리는 서버 및 클라이언트 컴포넌트가 독립적으로 진화할 수 있게 합니다.
      • 이는 웹에서 여러 조직 도메인 간의 협력과 상호운용성을 지원하는 데 중요합니다.
  • Stateless - 무상태성
    • 클라이언트와 서버 간의 통신은 상태를 가지면 안 되며, 각 클라이언트 요청은 해당 요청을 이해하는 데 필요한 모든 정보를 포함해야 합니다. 서버는 클라이언트의 상태를 유지하지 않으며, 세션 상태는 클라이언트에게 완전히 맡겨집니다.
  • Cacheable - 캐싱 가능성
    • 클라이언트 - 캐시 - 서버 → 동일한 요청을 반복적으로 줄때 계속 서버를 거친다면 비효율적이지만 캐시 서버를 배치해 효율적이고 빠르게 데이터를 응답받을 수 있습니다.
    • 단점 - 캐시가 신선하지 않은 데이터로 인해 신뢰성을 감소시킬 수 있다는 것입니다. 캐시에 있는 데이터가 서버로 직접 요청을 보낼 경우 얻게 될 데이터와 크게 다르다면 문제가 발생할 수 있습니다.

    Untitled

  • Layered System - 계층 구조 아키텍쳐
    • 계층형 시스템 스타일을 사용하면, 각 구성 요소가 상호 작용하는 직계 계층 너머를 볼 수 없도록 구성 요소 동작을 제한하여(=캡슐화하여) 아키텍처를 계층적으로 구성해야 한다.
  • 코드온디맨드 - Code on Demend
    • 서버에서 코드를 클라이언트로 보내서 실행할 수 있어야 한다.

      → ex) 서버로부터 받은 JavaScript 파일을 브라우저에서 실행시킬 수 있다.

    • REST를 사용하면 애플릿 또는 스크립트 형태로 코드를 다운로드하고 실행하여 클라이언트 기능을 확장 할 수 있습니다. 이는 사전 구현에 필요한 기능의 수를 줄여 클라이언트를 단순화합니다.

  • 균일한 인터페이스(Uniform interface) - REST 아키텍처 스타일이 다른 네트워크 기반 아키텍처 스타일과 구분되는 핵심적인 특징은 REST를 이루는 컴포넌트간의 uniform interface입니다. 컴포넌트간의 인터페이스에 소프트웨어 공학의 원칙인 “일반성(generality)”을 적용함으로써, 전체적인 시스템 아키텍처는 단순화되고 상호작용의 가시성(visibility)은 향상됩니다.
  • 단점 - 표준화된 형식으로 정보를 전송하므로 효율성이 저하된다는 것입니다.
  • 리소스 식별 (Identification of Resources) : 리소스가 URI로 식별되면 된다.
    • HTTP에서는 HTTP 요청 대상을 리소스라고 부른다. (문서, 사진, 다른 어떤것들)
    • 리소스는 리소스 식별을 위해 HTTP 전체에서 사용되는 URI에 의해 식별된다.
    • HTTP를 통해 REST API를 빌드하면, URL을 사용하여 API에서 액세스하는 리소스를 식별 할 수 있다. REST 제약 조건을 충족하려면 각 URL이 단일 리소스에 매핑되어야 하며 이 리소스에 대한 모든 액세스는 해당 URL을 통해 수행된다. 즉, 특정 리소스는 오직 하나의 URL만 가져야 한다. 예를 들어, 배송 애플리케이션에 대한 API를 제공하려는 경우 주문을 나타내는 리소스가 있을 수 있다. 번호 12345 가 매겨진 개별 주문의 URL에는 주문 번호가 포함된 경로가 있다.
  • 표현을 통한 자원 조작(Manipulation Of Resource through Representations)
    • RESTful 애플리케이션은 동일한 URI에서 동일한 리소스의 두 개 이상의 표현을 지원할 수 있다.
    • HTTP 메서드인 GET, POST, PUT, DELETE 등을 활용해서 리소스를 조작할 수 있다.
    • 자원에 대한 요청을 할 때, 서버는 자원의 표현(Resource Representation)으로 응답한다. 이 표현은 클라이언트가 이해하고 조작 할 수 있는 형식으로 리소스의 현재 상태를 캡처한다. 표현(Representation)을 추상적으로 설명하면 ‘메타 데이터를 가진 바이트 덩어리’라고 할 수 있다. 이 메타 데이터를 표현(Representation)의 미디어 타입이라고 한다.

https://example.org/greeting 라는 uri가 가리키는 리소스이다.

  • Self-descriptive message

    메세지가 스스로를 설명할 수 있어야 한다. (메세지만 보고서 그 의미를 이해를 할 수 있어야한다.)

    아래의 응답을 본다면 의미를 이해할 수 있을까??

      {"id":1,"name":"제이슨"}
    

    물론 유추는 할 수 있을 것이다. 하지만 정확히는 알 수 없다. 생각을 해보자면 흐름은 아래와 같을 것 이다.

    1. 요청이 정상적으로 처리되었는가? => 요청의 대한 결과의 상태가 없기때문에, 정상적으로 처리되었는지 아닌지 알 수 없다.
    2. 어떤 형식으로 작성되었는가? => JSON을 알고있는 사람들은 대부분 JSON이라고 답하겠지만, JSON이 아닌 누군가가 만든 content type일수도 있다. 그렇다면 파싱의 방식이 분명하지 못하게된다.
    3. (위의 content type이 application/json이라고 가정해보자) id라고 표기되어있는 key가 어떤 의미를 가지는지, name은 또 사람의 이름인지 제품의 이름인지 알수가 없다.

    그렇다면 어떻게 작성하면 self-descriptive message가 될까?

      1. HTTP/1.1 200 OK
      2. Content-Type: application/json
      3. {"id":1,"name":"제이슨"}
    

    위와 같이 작성하면 1번과 2번의 경우, 해결된 것 처럼 보인다. 하지만 key, value가 각각 어떤 의미를 가지는지는 알 수 없다. 이는 다음의 두가지 방법으로 명세를 제공해 처리할 수 있을 것이다.

    1. media-type을 정의
    2. Link header에 명세를 추가

    self-descriptive하게 메세지를 제공함으로서, 서버가 제공하는 내용을 클라이언트는 명확히 이해할 수 있고 변경이 있는 경우에도 어렵지 않게 적용할 수 있게 된다.

    REST에서는 메시지가 자기 서술적(self-discriptive)이며, 메시지 자체만으로 그 의미를 파악할 수 있기 때문에, 데이터를 효과적으로 전송할 수 있게 되는 것이다. 이 부분이 REST가 가지는 장점이 아닐까 라는 생각이 든다.

4) HATEOAS (hypermedia as the engine of application state)

애플리케이션의 상태가 Hyperlink를 이용해 전이되어야 한다. (대부분 거의 잘 안 지켜진다.)

자세한 설명

  • 어디서 어디로 전이가 가능한지 미리 결정되지 않는다. 어떤 상태로 전이가 완료되고 나서야 그 다음 전이될 수 있는 상태가 결정된다. 쉽게 말해서 링크는 동적으로 변경될 수 있다.
  • 리소스(Resource)를 고유하게 식별하고, 표현(Representation)을 사용하여 리소스 상태를 전달하고, 미디어 타입을 통해 self-descriptive 메시지를 사용함으로써 모든 애플리케이션 상태가 클라이언트에 유지된다. 모든 애플리케이션 상태를 클라이언트에 유지함으로써, 클라이언트와 서버 간의 직접 연결이 필요하지 않게 된다. 이로써 최소한의 리소스로 많은 클라이언트에 서비스를 제공하도록 서버를 확장 할 수 있다. 이러한 특징은 웹을 확장 가능하고 탄력적으로 만들어주었다. 결론적으로 REST 제약 조건으로 API를 설계함으로써, 확장 가능하고 탄력적인 API를 구축 할 수 있다.
  • 특정 리소스가 다른 리소스와 관련이 있을 때에는, 특정 리소스가 다른 리소스의 관련 정보를 가져올 수 있게 URI를 의미하는 링크(HATEOAS)를 포함해야 한다.

장점

  • 요청 URI가 변경되더라도 클라이언트에서 동적으로 생성된 URI를 사용함으로써, 클라이언트가 URI 수정에 따른 코드를 변경하지 않아도 되는 편리함을 제공한다.
  • URI 정보를 통해 들어오는 요청을 예측할 수 있게 된다.
  • Resource가 포함된 URI를 보여주기 때문에, Resource에 대한 신뢰를 얻을 수 있다.
  • 클라이언트가 제공되는 API의 변화에 일일이 대응하지 않아도 되는 편리함을 얻을 수 있다.

uniform한 interface를 얻기 위해서는 각 컴포넌트가 어떤 방식으로 동작하게 하는 다양한 아키텍처 제약조건들이 필요합니다.

REST는 4가지 제약조건에 의해 정의됩니다.

1. identification of resources

2. manipulation of resources through representations

3. self-descriptive messages

4. hypermedia as the engine of application state

HTTP에서의 representation

GET 메서드의 정의는 다음과 같다.

The GET method requests transfer of a current selected representation
for the target resource.

즉, target resource에 대한 현재의 선택된 representation 하나를 반환한다.

“target resource”란 https://example.org/greeting 라는 uri가 가리키는 리소스이다

hello” 라는 텍스트 자체가 리소스가 아니라, “환영의 의미를 담은 문서”가 리소스가 된다고 볼 수 있을 것이다.

일단 “representation”은 무엇인가? 어떤 리소스의 특정 시점의 상태를 반영하고 있는 정보이다. 하나의 representation은 representation data와 representation metadata로 구성된다. 위의 예에서는 “hello”가 representation data이고, “Content-Type: text/plain”과 “Content-Language: en”이 representation metadata이다. (HTTP 헤더들 중 representation metadata에 해당하는 것이 있고 그렇지 않은 것이 있다.)

“현재”란 무엇인가? 이것은 말 그대로 해석하면 될 것이다. 만약 https://example.org/greeting 가 가리키는 리소스의 representation이 “hi”에서 “hello”로 수정되었다면 “현재” representation은 “hi”가 아닌 “hello”가 될 것이다.

“선택된”이라고 함은 무슨 뜻인가? 이는 하나의 리소스의 현재 representation이 하나 이상이 될 수 있으며, 그 중 하나가 선택되었음을 의미한다. 즉 “greeting” 리소스의 현재 representation은, 영어 사용자를 위한 “hello”, 한국어 사용자를 위한 “안녕하세요”, HTML 문서를 원하는 클라이언트를 위한 “<html><body>hello</body></html>”등 여러가지가 될 수 있는데, 이들 중 하나가 선택되었다는 의미이다. metadata를 포함하여 representation들의 예를 들어보자.


참조

[REST API] Roy Fielding 의 REST API 논문 번역 및 이해(3) : 네이버 블로그 (naver.com)

REST의 기본 원칙 6가지 · Just Do It! And Then Some! (jaeseongdev.github.io)

Fielding Dissertation: CHAPTER 5: Representational State Transfer (REST) (uci.edu)

REST의 representation이란 무엇인가 – eungjun (npcode.com)

Categories:

Updated:

Leave a comment