본문 바로가기

ComputerScience/Network

[Network] RESTful web API design

이미지 출처: https://res.cloudinary.com/practicaldev/image/fetch/s--RK-AgEnh--/c_imagga_scale,f_auto,fl_progressive,h_900,q_auto,w_1600/https://dev-to-uploads.s3.amazonaws.com/i/1s3bedypkt7zm8maikzg.png

REST

REST 아키텍처 스타일은 웹이 1991년에 팀 버너스 리에 의해 탄생함으로써 시작되었습니다. 웹은 하이퍼텍스트를 활용하여 정보를 연결하는 방식으로, 인터넷에서 정보를 공유하는 방법을 제시했습니다.

웹의 기본 구성 요소는 다음과 같습니다.

  • 표현 형식: HTML
  • 식별자: URI
  • 전송 방법: HTTP

HTTP는 정보를 웹에서 전송하는 데 사용되는 프로토콜로, 1994년에 로이 필딩이 주도하여 개발되었습니다. 필딩은 HTTP 1.0의 명세 작업에 참여하면서, 기존의 웹과 호환성을 유지하면서 HTTP를 개선하고자 했습니다. 그는 HTTP Object Model 개념을 도입하여 HTTP를 객체 지향적으로 설계할 수 있는 방법을 제시했습니다. 이후, 2000년에 "Representational State Transfer: An Architectural Style for Distributed Hypermedia Interaction"라는 논문을 통해 REST 아키텍처 스타일을 발표했습니다.

REST는 하이퍼미디어 기반 분산 시스템을 구축하기 위한 아키텍처 스타일입니다.

 

REST는 다음과 같은 특징을 가지고 있습니다.

 

1. Client-Server (클라이언트-서버)

   - REST는 클라이언트와 서버 간의 역할을 명확히 분리하는 아키텍처 스타일입니다. 클라이언트는 사용자 인터페이스 및 사용자 관리에 집중하고, 서버는 데이터 저장, 처리, 비즈니스 로직을 처리하는 데 중점을 둡니다.
   - 이 구조는 시스템의 확장성을 높이고, 각 컴포넌트 간의 독립성을 유지하여 시스템을 효과적으로 관리할 수 있게 합니다.

 

2. Stateless (상태 비저장)

   - 각 클라이언트 요청은 서버에 모든 필요한 정보를 포함하고 있어야 하며, 서버는 해당 요청에 대한 상태를 저장하지 않습니다. 각 요청은 독립적으로 처리되며, 이전 요청과 상태에 대한 의존성이 없습니다.
   - 서버의 부하가 감소하며, 확장성이 향상되며, 클라이언트와 서버 간의 상호작용이 간단해집니다.

 

3. Cache (캐시)

   - REST는 응답을 캐시할 수 있는 기능을 제공하며, 클라이언트는 캐시된 리소스를 활용하여 동일한 요청에 대한 성능을 향상시킬 수 있습니다. 서버는 응답에 캐시 지시자를 포함하여 클라이언트가 얼마나 오래 캐시를 사용해야 하는지 알려줍니다.
   - 네트워크 부하를 감소시키고 성능을 향상시키며, 전체적인 시스템 효율성을 높입니다.

4. Uniform Interface (유니폼 인터페이스)
   - REST의 핵심 원칙 중 하나로, 모든 리소스에 대해 일관된 인터페이스를 제공하는 것입니다. 일관된 방식으로 리소스를 식별하고 조작하기 위해 표준화된 리소스 식별자, 표준화된 표현 형식, 자기 서술적 메시지 등이 사용됩니다.
   - 클라이언트와 서버 간의 상호 운용성을 향상시키고, 시스템의 단순성과 확장성을 유지합니다.

 

* Uniform Interface 제약 조건

  • Identification of resources: URI로 리소스가 식별되어야 함
  • Manipulation of resources through representations:  representation 전송을 통해서 리소스를 조작해야되어야 함
  • Self-descriptive messages: 메시지를 봤을 때 메시지의 내용으로 온전히 해석이 다 가능해야 함
  • Hypermedia as the engine of application state(HATEOAS): 표현에 포함된 하이퍼미디어 링크를 사용하여 애플리케이션 상태를 제어할 수 있어야함.

5. Layered System (계층형 시스템)
   - REST 아키텍처는 계층 구조를 가질 수 있으며, 각 계층은 특정한 역할과 책임을 갖습니다. 각 계층은 그 위의 계층에 대해 알 필요가 없으며, 각 계층은 독립적으로 개선될 수 있습니다.
   - 시스템의 모듈화 및 유지보수성이 향상되며, 각 계층의 재사용성이 높아집니다.

6. Code-on-Demand (optional) (선택적 코드 전송)
   - REST 아키텍처는 클라이언트에게 실행 가능한 코드를 제공할 수 있는 선택적인 특징을 가지고 있습니다. 클라이언트는 서버에서 전송된 코드를 실행할 수 있으며, 이는 클라이언트의 기능을 동적으로 확장하는 데 사용될 수 있습니다.
   - 클라이언트의 업데이트나 확장을 간편하게 하며, 일부 기능을 동적으로 로드하여 불필요한 초기 로딩을 방지할 수 있습니다.

잘 지켜지지 않는 REST API의 특징: Self-descriptive messages, HATEOAS

Self-descriptive messages

 

메시지 자체가 스스로를 설명해야 한다는 원칙을 의미합니다. 예를 들어, 다음과 같은 메시지를 고려해봅시다.

GET / HTTP/1.1


이 메시지는 루트를 얻어오는 GET 요청임을 나타내고 있습니다.

그러나 이 HTTP 요청 메시지는 목적지가 명시되어 있지 않아 Self-descriptive하지 못합니다.

 

목적지를 명시하는 경우:

GET / HTTP/1.1
Host: http://www.example.org

 

이 경우에는 http://www.example.org로 요청이 전송되는 목적지가 명시되어 있어야 Self-descriptive하다고 할 수 있습니다.

또 다른 예시로, 다음은 200 응답 메시지이며 JSON 본문이 포함된 경우입니다.

HTTP/1.1 200 OK
[ { "op": "remove", "path": "/a/b/c" } ]


그러나 이 응답 메시지는 클라이언트가 해석하기 어렵습니다. 

이 메시지를 해석하려면 Content-Type 헤더가 필요하며, JSON 형식임을 나타내야 합니다.

 

Content-Type 헤더를 추가한 경우:

HTTP/1.1 200 OK
Content-Type: application/json

[ { "op": "remove", "path": "/a/b/c" } ]

 

여기서도 메시지의 의미를 완전히 이해하려면, Content-Type 헤더에 json+patch+json이 명시되어야 합니다.

HTTP/1.1 200 OK
Content-Type: application/json-patch+json

[ { "op": "remove", "path": "/a/b/c" } ]


이렇게 하면 이제 메시지가 json-patch+json 미디어 타입으로 정의된 메시지임을 나타내므로, 클라이언트는 해당 명세를 참고하여 메시지를 해석할 수 있게 됩니다.

HATEOAS

HATEOAS(Hypermedia as the Engine of Application State)는 표현에 포함된 하이퍼미디어 링크를 사용하여 애플리케이션 상태를 제어하는 방식입니다.

REST를 실행하는 기본적인 동기 중 하나는 URI 체계에 대해 미리 알고 있지 않아도 전체 리소스 집합을 탐색할 수 있어야 하기 때문입니다.

각 HTTP GET 요청은 응답에 포함된 하이퍼링크를 통해 요청된 개체와 직접 관련된 리소스를 찾는 데 필요한 정보를 반환해야 하며, 이러한 각 리소스에 대해 사용할 수 있는 작업을 설명하는 정보도 제공되어야 합니다.

이 원칙을 HATEOAS(Hypertext as the Engine of Application State)라 합니다.

시스템은 실질적으로 유한 상태 시스템으로서, 각 요청에 대한 응답은 한 상태에서 다른 상태로 바꾸는 데 필요한 정보를 포함하고 있으며, 다른 정보는 필요하지 않습니다.

 

예를 들어 주문과 고객 간의 관계를 처리하기 위해 주문 고객에게 사용 가능한 작업을 식별하는 링크를 주문 표현에 포함할 수 있습니다. 다음은 가능한 표현입니다.

 

{
  "orderID":3,
  "productID":2,
  "quantity":4,
  "orderValue":16.60,
  "links":[
    {
      "rel":"customer",
      "href":"https://adventure-works.com/customers/3",
      "action":"GET",
      "types":["text/xml","application/json"]
    },
    {
      "rel":"customer",
      "href":"https://adventure-works.com/customers/3",
      "action":"PUT",
      "types":["application/x-www-form-urlencoded"]
    },
    {
      "rel":"customer",
      "href":"https://adventure-works.com/customers/3",
      "action":"DELETE",
      "types":[]
    },
    {
      "rel":"self",
      "href":"https://adventure-works.com/orders/3",
      "action":"GET",
      "types":["text/xml","application/json"]
    },
    {
      "rel":"self",
      "href":"https://adventure-works.com/orders/3",
      "action":"PUT",
      "types":["application/x-www-form-urlencoded"]
    },
    {
      "rel":"self",
      "href":"https://adventure-works.com/orders/3",
      "action":"DELETE",
      "types":[]
    }]
}

 

RESTful API기본 디자인 원칙

RESTful API는 HTTP를 기반으로 하는 웹 API의 일종으로, 다음과 같은 기본 디자인 원칙을 따릅니다.

 

리소스 기반

모든 데이터를 리소스로 표현합니다. 리소스는 URI로 식별되며, HTTP 메서드를 사용하여 리소스에 대한 작업을 수행합니다.

예를 들어 특정 고객 주문의 URI는 다음과 같습니다

https://adventure-works.com/orders/1

 

클라이언트가 리소스의 _표현_을 교환하여 서비스와 상호 작용합니다. 많은 Web API가 교환 형식으로 JSON을 사용합니다. 예를 들어 위에 나열된 URI에 대한 GET 요청은 이 응답 본문을 반환할 수 있습니다.

{"orderId":1,"orderValue":99.90,"productId":1,"quantity":1}

 

균일한 인터페이스

REST API는 균일한 인터페이스를 사용하므로 클라이언트와 서비스 구현을 분리하는 데 도움이 됩니다. HTTP를 기반으로 하는 REST API의 경우 리소스에 표준 HTTP 동사 수행 작업을 사용하는 것이 균일한 인터페이스에 포함됩니다. 가장 일반적인 작업은 GET, POST, PUT, PATCH 및 DELETE입니다.

 

상태 비저장

REST API는 상태 비저장 요청 모델을 사용합니다. HTTP 요청은 독립적이어야 하고 임의 순서로 발생할 수 있으므로, 요청 사이에 일시적인 상태 정보를 유지할 수 없습니다. 정보는 리소스 자체에만 저장되며 각 요청은 자동 작업이어야 합니다. 이러한 제약 조건이 있기 때문에 웹 서비스의 확장성이 우수합니다. 클라이언트와 특정 서버 사이에 선호도를 유지할 필요가 없기 때문입니다. 모든 서버는 모든 클라이언트의 모든 요청을 처리할 수 있습니다. 그렇긴 하지만, 다른 요소가 확장성을 제한할 수 있습니다. 예를 들어 많은 웹 서비스가 백 엔드 데이터 저장소에 데이터를 쓰며, 이 경우 스케일 아웃이 어려울 수 있습니다.

 

하이퍼미디어

표현에 포함된 하이퍼미디어 링크에 따라 구동됩니다.

예를 들어 다음은 주문의 JSON 표현을 보여줍니다. 주문과 관련된 고객을 가져오거나 업데이트하는 링크를 포함하고 있습니다.

{
  "orderID":3,
  "productID":2,
  "quantity":4,
  "orderValue":16.60,
  "links": [
    {"rel":"product","href":"https://adventure-works.com/customers/3", "action":"GET" },
    {"rel":"product","href":"https://adventure-works.com/customers/3", "action":"PUT" }
  ]
}

RESTful API 성숙도 모델

Leonard Richardson은 Web API에 대한 성숙도 모델을 제안했습니다.

 

- 수준 0: 한 URI를 정의합니다. 모든 작업은 이 URI에 대한 POST 요청입니다.

- 수준 1: 개별 리소스에 대한 별도의 URI를 만듭니다.

- 수준 2: HTTP 메서드를 사용하여 리소스에 대한 작업을 정의합니다.

- 수준 3: 하이퍼미디어(HATEOAS)를 사용합니다.

 

수준 3은 Fielding의 정의에 따르면 진정한 RESTful API에 해당합니다. 실제로 게시된 여러 Web API가 수준 2의 어딘가에 해당합니다.

리소스 중심의 API 디자인

API는 비즈니스 엔터티에 중점을 두어야 합니다.

예를 들어, 전자 상거래 시스템에서는 주문 및 고객과 같은 기본 엔터티에 집중합니다.

소스 URI는 동사(작업)가 아닌 명사(리소스)를 기반으로 하며, REST의 목적은 엔터티 및 해당 엔터티에서 수행할 수 있는 작업을 모델링하는 것입니다.

https://adventure-works.com/orders // Good

https://adventure-works.com/create-order // Avoid

 

 

위 URI에 HTTP GET 요청을 보내면 컬렉션에 있는 항목 목록을 검색합니다. 또한 컬렉션의 항목마다 고유의 URI가 있습니다. 항목의 URI에 대한 HTTP GET 요청은 해당 항목의 세부 정보를 반환합니다.

URI에 일관적인 명명 규칙을 적용합니다. 일반적으로 이렇게 하면 컬렉션을 참조하는 URI에 대해 복수 명사를 사용할 수 있습니다.

 

URI는 컬렉션과 항목을 구분하여 일관적인 명명 규칙을 적용합니다. 예를 들어, /customers는 고객 컬렉션을 나타내고, /customers/5는 ID가 5인 고객을 나타냅니다.

URI를 간단하게 유지하면 API를 직관적으로 유지할 수 있습니다.

또한 많은 Web API 프레임워크는 매개 변수가 있는 URI 경로를 기반으로 요청을 라우팅할 수 있으므로 개발자는 경로 /customers/{id}에 대한 경로를 정의할 수 있습니다.

 

리소스 간의 관계를 고려하여 URI를 구성합니다. 예를 들어, /customers/5/orders는 특정 고객의 주문 목록을 나타냅니다.

 좀 더 복잡한 시스템에서는 /customers/1/orders/99/products처럼 클라이언트가 여러 관계 수준을 탐색할 수 있는 URI를 제공하고 싶을 수 있습니다. 그러나 이 수준의 복잡성은 유지하기 어려울 수 있으며 나중에 리소스 사이의 관계가 변하면 유연성이 떨어집니다. 그 대신 URI를 비교적 간단하게 유지해 보세요. 애플리케이션이 리소스 참조를 지정한 후에는 이 참조를 사용하여 해당 리소스와 관련된 항목을 찾을 수 있어야 합니다. 이전 쿼리를 /customers/1/orders URI로 바꿔서 고객 1의 모든 주문을 찾은 후 /orders/99/products로 바꿔서 이 주문의 제품을 찾을 수 있습니다.

복잡성을 피하기 위해 HATEOAS를 활용하여 HTTP 응답 메시지의 본문에 연결된 리소스에 대한 탐색 가능한 링크를 제공합니다.

 

효율적인 리소스 관리를 위해 API는 번잡한 작은 리소스보다는 관련 정보를 통합한 큰 리소스를 통해 데이터를 검색하는 방식을 고려해야 합니다. 클라이언트의 요구에 따라 데이터를 비정규화하고, 단일 요청으로 여러 관련 정보를 검색할 수 있는 큰 리소스로 결합합니다.

 

Web API는 기본 데이터 원본과의 종속성을 최소화해야 합니다. 데이터베이스에 저장되는 경우, Web API는 데이터베이스의 추상화로 생각되어야 하며, 매핑 계층을 도입하여 클라이언트를 데이터베이스의 변경 내용으로부터 격리시켜야 합니다.

 

URI의 일관성 유지를 위해서 리소스 URI를 컬렉션/항목/컬렉션보다 더 복잡하게 만들지 않는 것이 좋습니다.

복잡한 URI는 웹 서버의 부하를 높일 수 있으므로 번잡한 API는 피해야 합니다.

 

마지막으로 특정 리소스가 아닌 작업을 수행해야 할 때는 의사 리소스를 고려합니다.

예를 들어 URI /add?operand1=99&operand2=1에 대한 GET 요청은 본문에 값 100이 포함된 응답 메시지를 반환합니다.

그러나 이러한 형식의 URI는 제한적으로만 사용해야 합니다.

HTTP 메서드 측면에서 API 작업 정의

HTTP 프로토콜은 요청에 의미 체계를 할당하는 다양한 메서드를 정의합니다. 대부분의 RESTful 웹 API에서 사용하는 일반적인 HTTP 메서드는 다음과 같습니다.

 

GET

지정된 URI에서 리소스의 표현을 검색합니다. 응답 메시지의 본문은 요청된 리소스의 세부 정보를 포함하고 있습니다.

성공적인 GET 메서드는 일반적으로 HTTP 상태 코드 200(정상)를 반환합니다. 리소스를 찾을 수 없는 경우 메서드가 404(찾을 수 없음)를 반환해야 합니다.

요청이 처리되었지만 HTTP 응답에 포함된 응답 본문이 없는 경우 HTTP 상태 코드 204(콘텐츠 없음)를 반환해야 합니다. 예를 들어 일치 항목이 없는 검색 작업을 이 동작으로 구현할 수 있습니다.

 

POST

지정된 URI에 새 리소스를 만듭니다. 요청 메시지의 본문은 새 리소스의 세부 정보를 제공합니다.

POST 메서드는 새 리소스를 만드는 경우 HTTP 상태 코드 201(만들어짐)을 반환합니다. 새 리소스의 URI는 응답의 Location 헤더에 포함됩니다. 응답 본문은 리소스의 표현을 포함합니다.

이 메서드가 일부 처리를 수행하지만 새 리소스를 만들지 않는 경우 메서드는 HTTP 상태 코드 200을 반환하고 작업의 결과를 응답 본문에 포함할 수 있습니다. 또는 반환할 결과가 없으면 메서드가 응답 본문 없이 HTTP 상태 코드 204(내용 없음)를 반환할 수 있습니다.

클라이언트가 잘못된 데이터를 요청에 배치하면 서버에서 HTTP 상태 코드 400(잘못된 요청)을 반환해야 합니다. 응답 본문에는 오류에 대한 추가 정보 또는 자세한 정보를 제공하는 URI 링크가 포함될 수 있습니다.

 

PUT

지정된 URI에 리소스를 만들거나 대체합니다. 요청 메시지의 본문은 만들 또는 업데이트할 리소스를 지정합니다.

PUT 메서드는 POST 메서드와 마찬가지로 새 리소스를 만드는 경우 HTTP 상태 코드 201(만들어짐)을 반환합니다. 이 메서드는 기존 리소스를 업데이트할 경우 200(정상) 또는 204(내용 없음)를 반환합니다. 상황에 따라 기존 리소스를 업데이트할 수 없는 경우도 있습니다. 이 경우 HTTP 상태 코드 409(충돌)를 반환하는 방안을 고려해야 합니다.

 

컬렉션의 복수 리소스에 대한 업데이트를 일괄 처리할 수 있는 일괄 HTTP PUT 작업의 구현을 생각해 보겠습니다. PUT 요청은 컬렉션의 URI를 지정해야 하며, 요청 본문에 수정할 리소스의 세부 정보를 지정해야 합니다. 이 접근 방식은 데이터 전송량을 줄이고 성능을 향상시킬 수 있습니다.

 

PATCH

리소스의 부분 업데이트를 수행합니다. 요청 본문은 리소스에 적용할 변경 내용을 지정합니다.

클라이언트는 PATCH 요청을 사용하여 업데이트를 패치 문서 형태로 기존 리소스에 보냅니다. 서버는 패치 문서를 처리하여 업데이트를 수행합니다. 패치 문서는 리소스 전체가 아니라 적용할 변경 내용만 설명합니다.

예를 들어 원래 리소스의 JSON 표현은 다음과 같습니다.

{
    "name":"gizmo",
    "category":"widgets",
    "color":"blue",
    "price":10
}

이 리소스에 가능한 JSON Patch 요청은 다음과 같습니다.

{
    "price":12,
    "color":null,
    "size":"small"
}

이는 서버에 price를 업데이트하고 color를 삭제하고 size를 추가하도록 지시하지만 name category는 수정되지 않습니다.

JSON 병합 패치의 미디어 유형은 application/merge-patch+json입니다.

 

DELETE

지정된 URI의 리소스를 제거합니다.

특정 요청의 효과는 리소스가 컬렉션인지 아니면 개별 항목인지에 따라 달라집니다. 다음 표는 전자 상거래 예제를 사용하여 대부분의 RESTful 구현에서 적용하는 일반적인 규칙을 요약합니다. 이러한 요청 중 일부는 특정 시나리오에 따라 구현되지 않을 수 있습니다.

삭제 작업이 성공하면 웹 서버는 프로세스가 성공적으로 처리되었지만 응답 본문에 추가 정보가 없음을 나타내는 HTTP 상태 코드 204(콘텐츠 없음)로 응답해야 합니다. 리소스가 없는 경우 웹 서버는 HTTP 404(찾을 수 없음)를 반환할 수 있습니다.

 

POST, PUT, PATCH의 차이점

POST, PUT, PATCH의 차이점은 다음과 같습니다.

 

POST

리소스를 만듭니다. 서버는 새 리소스에 대한 URI를 할당하고 클라이언트에 해당 URI를 반환합니다. REST 모델에서는 컬렉션에 POST 요청을 자주 적용합니다. 새 리소스가 컬렉션에 추가됩니다. POST 요청은 새 리소스를 만들지 않고 기존 리소스에 처리할 데이터를 보내는데 사용할 수도 있습니다.

 

PUT

리소스를 만들거나 또는 기존 리소스를 업데이트합니다. 클라이언트는 리소스의 URI를 지정합니다. 요청 본문에는 리소스의 완전한 표현이 포함됩니다. 이 URI를 사용하는 리소스가 이미 있으면 리소스가 대체됩니다. 아직 없고 서버에서 리소스 만들기를 지원하는 경우 새 리소스가 생성됩니다. PUT 요청은 컬렉션보다는 특정 고객 같은 개별 항목인 리소스에 가장 자주 적용됩니다. 서버에서 PUT을 통한 업데이트를 지원하지만 만들기는 지원하지 않을 수 있습니다. PUT을 통한 만들기 지원 여부는 리소스가 존재하기 전에 클라이언트가 의미 있는 방법으로 리소스에 URI를 할당할 수 있는지 여부에 따라 결정됩니다. 할당할 수 없는 경우 POST를 사용하여 리소스를 만들고 PUT 또는 PATCH를 사용하여 업데이트합니다.

 

PATCH

기존 리소스에 부분 업데이트를 수행합니다. 클라이언트는 리소스의 URI를 지정합니다. 요청 본문은 리소스에 적용할 변경 내용을 지정합니다. 클라이언트가 리소스의 전체 표현이 아닌 변경 내용만 보내기 때문에 PUT을 사용하는 것보다 이 방법이 더 효율적일 수 있습니다. 또한 서버에서 리소스 만들기를 지원하는 경우 기술적으로 PATCH는 새 리소스를 만들 수 있습니다("null" 리소스에 대한 업데이트를 지정하여).

PUT 요청은 idempotent여야 합니다. 클라이언트가 동일한 PUT 요청을 여러 번 제출하는 경우 그 결과가 항상 같아야 합니다(같은 값을 사용하여 같은 리소스가 수정되므로). POST 및 PATCH 요청이 반드시 idempotent가 된다는 보장은 없습니다.

미디어 유형

클라이언트와 서버는 리소스 표현을 교환합니다. 예를 들어 POST 요청에서는 요청 본문에 만들 리소스의 표현이 포함됩니다. GET 요청에서는 응답 본문에 가져온 리소스의 표현이 포함됩니다.

HTTP 프로토콜에서 형식은 MIME 유형이라고도 하는 _미디어 유형_을 사용하여 지정됩니다. 이진이 아닌 데이터의 경우 대부분의 웹 API는 JSON(미디어 형식 = application/json) 및 XML(미디어 형식 = application/xml)을 지원합니다.

요청 또는 응답의 Content-Type 헤더는 표현 형식을 지정합니다. 다음은 JSON 데이터를 포함하는 POST 요청의 예입니다.

POST https://adventure-works.com/orders HTTP/1.1
Content-Type: application/json; charset=utf-8
Content-Length: 57

{"Id":1,"Name":"Gizmo","Category":"Widgets","Price":1.99}

 

서버에서 미디어 유형을 지원하지 않으면 HTTP 상태 코드 415(지원되지 않는 미디어 유형)를 반환해야 합니다.

클라이언트 요청에는 클라이언트가 응답 메시지에서 서버로부터 받는 미디어 유형 목록을 포함하는 Accept 헤더가 포함될 수 있습니다. 예를 들면 다음과 같습니다.

GET https://adventure-works.com/orders/2 HTTP/1.1
Accept: application/json

서버가 나열된 미디어 유형 중 어떤 것도 일치시킬 수 없는 경우 HTTP 상태 코드 406(허용되지 않음)을 반환해야 합니다.

비동기 작업

때로는 POST, PUT, PATCH 또는 DELETE 작업을 완료하는 데 시간이 걸리는 처리가 필요할 수 있습니다. 처리 작업이 완료될 때까지 기다렸다가 클라이언트에 응답을 보내는 경우 허용되지 않는 수준의 대기 시간이 발생할 수 있습니다. 이 경우 비동기 작업을 수행하는 방안을 고려해 보아야 합니다. 요청 처리가 수락되었지만 아직 완료되지 않았음을 나타내는 HTTP 상태 코드 202(수락됨)를 반환합니다.

클라이언트가 상태 엔드포인트를 폴링하여 상태를 모니터링할 수 있도록 비동기 요청의 상태를 반환하는 엔드포인트를 표시해야 합니다. 202 응답의 Location 헤더에 상태 엔드포인트의 URI를 포함합니다.

예를 들면 다음과 같습니다.

HTTP/1.1 202 Accepted

Location: /api/status/12345

클라이언트가 이 엔드포인트에 GET 요청을 보내는 경우 응답에 요청의 현재 상태가 포함되어야 합니다. 필요에 따라 예상 완료 시간 또는 작업 취소 링크를 포함할 수 있습니다.

HTTP/1.1 200 OK

Content-Type: application/json

{

    "status":"In progress",

    "link": { "rel":"cancel", "method":"delete", "href":"/api/status/12345" }

}

 

비동기 작업에서 새 리소스를 만드는 경우 작업 완료 후 상태 엔드포인트에서 상태 코드 303(다른 항목 보기)을 반환해야 합니다. 303 응답에 새 리소스의 URI를 제공하는 Location 헤더를 포함합니다.

HTTP/1.1 303 See Other

Location: /api/orders/12345

이 방법을 구현하는 방법에 대한 자세한 내용은 장기 실행 요청에 대한 비동기 지원 제공비동기 요청-회신 패턴을 참조하세요.

REST가 준 웹의 독립적인 진화

1. Host 헤더 추가
   - HTTP/1.1에서 Host 헤더의 도입은 여러 도메인을 지원하는 가상 호스팅을 가능케 하였습니다.

2. 길이 제한 다루는 방법 명시
   - REST의 영향으로 HTTP 상태 코드가 명시되었습니다. 예를 들어, 414 URI Too Long이 도입되었습니다.

3. URI에서 리소스의 정의가 추상적으로 변경
   - REST의 영향으로 URI는 단순히 "문서의 위치"가 아닌 "식별하고자 하는 무언가"를 나타내는 추상적인 개념으로 진화하였습니다.

4. HTTP/1.1 명세 최신판에서 REST에 대한 언급
   - HTTP/1.1 명세의 최신 버전에서는 REST에 대한 언급이 포함되었으며, representaion의 개념도 도입되었습니다.

로이 필딩이 HTTP와 URI 명세의 저자 중 한 명이었기 때문에, REST는 이러한 변화에 지속적인 영향을 끼쳤습니다.

참고 자료

https://learn.microsoft.com/ko-kr/azure/architecture/best-practices/api-design

 

웹 API 디자인 모범 사례 - Azure Architecture Center

플랫폼 독립성과 서비스 진화를 지원하는 웹 API 설계를 위한 모범 사례를 알아봅니다.

learn.microsoft.com

https://velog.io/@kjh03160/%EA%B7%B8%EB%9F%B0-REST-API%EB%A1%9C-%EA%B4%9C%EC%B0%AE%EC%9D%80%EA%B0%80

 

그런 REST API로 괜찮은가?

개발 취준 톡방에서 ajax api가 REST API인지? 에 관한 질문에 어떤 분이 REST API의 정의를 다시 한 번 생각해보라면서, 아래의 동영상을 남겨주셨다.https://www.youtube.com/watch?v=RP_f5dMoHFc이에, 위 동영상

velog.io