본문 바로가기

[네트워크] Restful API 이해하기 (feat. 그런 REST API로 괜찮은가?)

들어가며

Restful API를 개발한다는 것은 무엇일까요. 그리고 Rest라는 것은 무엇일까요. 개발을 하면서, 한 번쯤은 들어보고, 알고 있다고 생각하는 개념이었는데, 누군가 나에게 Rest가 무엇인가요 물었을 때, 단 한 마디도 제대로 할 수 없었습니다. 이번 기회를 통해 Rest란 무엇이며, Restful 하다는 것은 무엇인지에 대해 그런 REST API로 괜찮은가? 자료를 활용해서 정리해보려 합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

REST의 출현 계기

1991년 www가 팀 버너스 리에 의해 탄생했습니다. 이때 어떻게 인터넷에서 정보를 공유할 것인가에 대해 고민을 시작합니다. 팀 버너스 리는 이에 대한 답으로 정보들을 하이퍼 텍스트로 연결하는 방법을 제시했습니다. 세부적인 방법으로는 표현 형식은 HTML이며, 식별자는 URI, 전송방법은 HTTP 방식을 제안했습니다. 이렇게 www의 등장으로 정보 공유/접근이 굉장히 쉬워졌습니다. 하지만 www의 접근성과 사용성 때문에 많은 사람들이 몰려들게 되었고 웹 상에서는 많은 기계들이 소통하면서 기존에는 없던 새로운 문제들이 생겨났습니다. 

 

 

첫 번째 문제는 클라이언트와 서버 간 결합도가 높다는 문제였습니다. A와 B가 웹 상에서 통신을 하고 있다고 가정하겠습니다. 그리고 각자 다른 프로토콜과 데이터 형식을 사용합니다. 각자 사용하는 통신 형식과 프로토콜이 다르다 보니 통신 대상이 누구냐에 따라서 사용해야 하는 프로토콜과 데이터 형식이 달라지게 됩니다. 이는 곧 클라이언트와 서버 간의 결합도가 높아졌다는 뜻을 의미하고, 서버의 변경이 클라이언트에 큰 영향을 끼치게 됐습니다. 만약 A가 B의 서버에 통신할 때 특정 프로토콜을 사용하니, 그 프로토콜에 맞게 코드를 작성했는데, B 서버가 갑자기 사용하는 프로토콜을 변경하면 A 서버에서는 장애가 발생할 수 밖에 없습니다. 

 

두 번째 문제는 자원의 표현 및 상태관리가 어렵다는 문제가 있었습니다. 예를 들어 회원 정보 생성이라는 기능을 담는데 A라는 사람은 /new-user라고 정의내리고, B라는 사람은 /new/user라고 설계했습니다. 이처럼 자원을 어떻게 관리할 지 표준이 부재했습니다. 이 때문에 높은 복잡도로 이어지게 됐습니다. 기존 웹은 정적 자원을 전송하기 위해 설계됐는데, 페이지 안의 정보가 많아지고 복잡해지다 보니 자원  관리가 어려워졌습니다. 그래서 조그마한 자원이 변경되더라도 페이지 전체를 다시 요청해야 하는 문제가 생겼습니다. 이는 네트워크 성능 문제로도 이어지게 됐습니다. 

 

이때 로이 필딩이라는 사람은  '웹을 망가뜨리지 않고 어떻게 http 기능을 증가시킬 수 있을까?' 고민합니다. 고민 끝에 HTTP Object Model이라는 것을 만들고, REST를 최초로 공개합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

API

한편 API라는 것이 있습니다. 98년에 마이크로소프트에서 원격으로 다른 시스템에 메서드를 호출할 수 있는 XML-RPC 프로토콜을 만들고, 이를 곧 SOAP라는 이름으로 바뀌며 Salesforce 회사가 인터넷에 최초로 공개합니다. 당시 SOAP을 이용해서 API를 만들었는데 이는 상당히 복잡합니다. 

 

출처 : 그런 REST API로 괜찮은가

 

 

너무 복잡한 탓에 Salesforce의 API는 많이 쓰이지 않았고, 반면 REST 방식은 단순하고, 규칙이 적다는 이유로 WWW의 API가 REST로 정착이 되나 싶었습니다. 2006년에 AWS는 자사 API 사용량의 85%가 REST임을 밝혔고, Salesforce 또한 2010년 REST API를 추가했습니다. 이렇게 WWW의 API가 REST로 정착이 되나 싶었습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

그것은 REST가 아니다.

2008년 CMS를 위한 표준으로 CMIS가 나왔습니다. IBM, 마이크로소프트와 같은 기업들이 함께 작업했으며, REST 바인딩을 지원한다고 발표했습니다. 하지만 이것을 본 로이는 아래와 같은 말을 합니다.

 

 

"No REST in CMIS"

 

 

 

다른 사람들이 볼 때는 충분히 REST처럼 보였지만, 정작 논문 저자인 로이는 아니라고 말합니다. 그리고 2016년 말, 마이크로소프트가 REST API 가이드라인을 만들었는데, 내용은 다음과 같았습니다.

 

URI는 https://{serviceRoot}/{collection}/{id} 형식이어야 함.
GET, PUT, DELETE, POST, HEAD, PATCH, OPTIONS를 지원해야 함.
API 버저닝은 Major.minor로 하고 URI에 버전 정보를 포함시킨다.
...

 

하지만 로이는 마이크로소프트의 가이드라인을 보며 이것은 그냥 http API라고 말하며, 블로그에 아래와 같은 말을 남깁니다.

 

"REST API must be hypertext-driven"
"REST API를 위한 최고의 버저닝 전략은 API 버저닝을 안 하는 것"

 

사람들이 알고 있던 REST API와 정작 만들었던 로이의 REST API는 너무나도 달랐던 문제가 있었는데, 무엇이 문제였고 왜 이런 차이가 발생한 것일까요? 이에 대해 알아보겠습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

REST API

REST API란 REST 아키텍처를 따르는 API입니다. REST란 분산 하이퍼미디어 시스템(ex. 웹)을 위한 아키텍처 스타일입니다. 아키텍처 스타일이란 제약 조건의 집합을 뜻합니다. 즉, REST에서 정의한 제약 조건을 모두 지켜야 REST를 따른다고 말할 수 있습니다. 그렇다면, REST에서 정의한 제약 조건이란 무엇이 있을까요? 이에 대해 알아보겠습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

REST를 구성하는 스타일

REST에서 정의한 제약조건은 6가지가 있습니다.

 

1. Client-Server 클라이언트 - 서버 구조
2. Stateless 무상태성
3. Cache 캐시가능성
4. Uniform Interface 균일한 인터페이스
5. Layered System 계층형 시스템
6. Code-on-Demand (optional) 주문형 코드

 

 

 

1. 클라이언트 - 서버 구조는 클라이언트는 요청을 발생시키고, 서버는 요청에 대해 반응해야 한다는 제약조건입니다. 관심사의 분리를 통해 클라이언트는 UI의 이식성에 집중할 수 있고, 서버는 확장성에만 집중할 수 있게 됩니다. 서버는 데이터만 전달하면 끝이고, 클라이언트는 데이터를 받아 원하는 UI로 구성하면 끝입니다. 

 

2. 무상태성은 요청은 상태를 가지지 않는다는 제약조건입니다. 즉, 각각의 요청은 독립적이고 필요한 모든 정보를 제공해야 한다는 제약조건입니다. 쉽게 말해, 서버는 클라이언트가 이전에 무슨 요청을 보냈는지 모른다는 뜻입니다. 

 

3. 캐시가능성은 서버는 자원이 캐시 가능한지 명시해야 한다는 제약조건입니다. 예를 들어 클라가 서버한테 API 요청을 할 때, 서버에서는 응답하는 데이터를 캐싱해도 된다는 마킹을 해줍니다. 클라이언트는 일정 시간 내에 다시 동일한 요청을 보내려고 할 때 요청을 생략할 수 있습니다. 

 

4. 계층형 시스템은 계층형 시스템을 적용해야 한다는 제약조건입니다. 만약 클라이언트가 서버에게 A + B + C에 해당하는 조건을 모두 수행하라고 메시지를 전달했다고 가정하겠습니다. 만약 서버가 계층형 시스템으로 구성되어 있다면 각각의 책임에 맞게 메시지를 해석할 수 있기 때문에 확장성에 유리합니다. 

 

5. 주문형 코드 제약조건은 클라이언트가 '필요에 의해' 기능을 확장할 수 있도록 해야한다는 제약조건입니다. 만약 클라이언트가 서버에게 앞으로 A라는 기능이 필요할 것 같다고 메시지를 보내면, 서버는 A를 실행할 수 있는 파일을 전달합니다. 이후에는 단순히 저장된 파일을 실행하기만 하면 되고, 클라에서 서버로 요청을 보낼 필요가 없습니다. 주문형 코드의 예시로는 플러그인이 있는데요. 클라이언트의 단순성을 향상시킨다는 이점이 존재하지만, 시스템 전체적으로 적용됐을 때 오히려 성능이 안 좋아지는 이슈가 발생될 수 있기 때문에 옵셔널한 제약조건입니다. 

 

6. 균일한 인터페이스는 개발을 할 때 클라이언트와 맞닿아 있는 부분(Http Request, Http Response 등)을 쉽고 일반적으로 설계하라는 제약조건입니다. 

 

대체로 REST라고 부르는 것들은 위의 조건을 대부분 지키고 있습니다. 왜냐하면 HTTP만 잘 따라도 Client-Server, Stateless, Cache, Layered System은 다 지킬 수 있기 때문입니다. 하지만 로이가 REST가 아니라고 말하는 것들은 Uniform Interface를 만족하지 못하는 것이 대부분입니다. Uniform Interface 역시 아키텍처 스타일이기 때문에 안에 뭐가 들어있는지 살펴보겠습니다. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

Uniform Interface 제약 조건

Uniform Interface 제약 조건에는 4가지가 있습니다.

 

1. Identification of resources
2. Manipulation of resources through representations
3. Self-descriptive messages
4. Hypermedia as the engine of application state(HATEOAS)

 

첫 번째, Identification of resources는 URI로 리소스가 식별되면 된다는 뜻입니다. 클라이언트와 서버 사이의 상호작용에서 고유하게 자원을 식별할 수 있어야 한다는 제약조건입니다. 

 

 

두 번째, Manipulation of resources through representations는 representation 전송을 통해서 리소스를 조작해야 된다는 뜻입니다. 조금 더 쉽게 리소스를 만들거나 삭제, 수정할 때 http 메시지에 그 표현을 전송해야 된다는 것입니다. 위 2가지 조건은 대부분 잘 지켜지고 있습니다. 하지만 문제는 아래 2개입니다. 이 2가지는 사실 우리가 REST API라고 부르는 것의 모든 것들을 지키지 못하고 있습니다. 그럼, Self-descriptive messages와 Hypermedia as the engine of application state이 무엇인지 자세하게 살펴보도록 하겠습니다. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

Self-descriptive messages

제목의 뜻은 '메시지는 스스로를 설명해야 한다'입니다. 예를 들어 아래와 같은 메시지가 있다고 해보겠습니다.

 

GET / HTTP/1.1

 

단순히 루트를 얻어오는 GET 요청입니다. 이 HTTP 요청 메시지는 뭔가 빠져 있어서 Self-descriptive 하지 못합니다. 우선 목적지가 빠져있습니다. 

 

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

 

이 요청이 www.example.org라는 도메인으로 간다라는 목적지가 빠져있기 때문에 이런 경우는 Self-descriptive하지 않다고 합니다.  

 

또 이런 것도 생각해볼 수 있습니다. 200 응답 메시지이며, JSON 본문이 있습니다.

 

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

 

이렇게 되면 당연히 Self-descriptive 하지 않는데, 그 이유는 이걸 클라이언트가 해석하려고 하면, 어떤 문법으로 작성된 것인지 모르기 때문에 해석에 실패합니다. 그렇기 때문에 Content-Type 헤더가 반드시 들어가야 합니다.

 

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

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

 

Content-Type 헤더에서 대괄호, 중괄호, 큰따옴표의 의미가 뭔지 알게 되어, 파싱이 가능하여 문법을 해석할 수 있게 됩니다. 그렇다면 이제 Self-descriptive 하다고 볼 수 있는가? 아닙니다. 그걸 해석했다고 하더라도, op 값은 무슨 뜻이고, path가 무엇을 의미하는지는 알 수 없습니다. 

 

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

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

 

이렇게 명시하면 완전해집니다. 이 응답은 json-patch+json이라는 미디어 타입으로 정의된 메시지이기 때문에 json-patch라는 명세를 찾아가서 이해한 다음, 이 메시지를 해석을 하면 그제야 올바르게 메시지의 의미를 이해할 수 있게 됩니다.

 

이처럼 Self-descriptive message라는 것은 메시지를 봤을 때 메시지의 내용으로 온전히 해석이 다 가능해야 된다는 것입니다. 하지만 오늘날의 REST API는 상당히 이를 만족하지 못하고 있습니다. 대부분 미디어 타입에는 그냥 json이라고만 되어있고 이를 어떻게 해석해야 되는지는 명시가 되어 있지 않습니다. 만약 자기서술적인 메시지를 구성하려면 Content-Type을 IANA에서 커스텀 media type을 등록해서 활용하는 방법도 있고, 메시지 헤더에 명세가 포함된 링크를 등록해서 자기서술적인 메시지를 구성할 순 있습니다. 

 

 

지금까지 Self-descriptive message에 대해 알아봤다면, 다음은 Hypermedia as the engine of application state(HATEOAS)에 대해 알아보겠습니다.  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

HATEOAS

Hypermedia as the engine of application state(HATEOAS)의 뜻은 애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다는 뜻입니다. 즉 클라이언트는 서버와 상호작용하면서 하이퍼링크를 통해 동적으로 모든 다른 리소스에 접근할 수 있어야 한다는 제약조건입니다. 이러한 방법은 클라이언트가 서버로부터 특정 요청을 할 때, 요청에 필요한 URI를 응답에 포함시켜 반환하는 것으로 가능하게 할 수 있습니다.

 

예를 들어, 계좌번호가 "12345"인 계좌의 정보를 조회하는 요청을 한다고 가정해보겠습니다. 기존의 전형적인 REST API 응답이라면 아래와 같이 나올 것입니다.

 

 

 

 

출처 : https://joomn11.tistory.com/26

 

 

하지만 HATEOAS가 적용된 응답(URI 정보를 응답에 추가)은 아래와 같습니다. 예를 들어 계좌번호가 "12345"인 계좌 정보를 조회한다면, 사용자는 다음 행동으로 현금 인출을 할 수 있고, 계좌 이체도 할 수 있습니다. 그럼 해당 계좌의 상태에 따라 접근 가능한 추가 API들이 links라는 이름으로 제공됩니다.

 

 

출처 : https://joomn11.tistory.com/26

 

 

 

 

즉, 계좌 번호를 조회(GET)하는 요청 이후, 이를 조회, 수정, 삭제할 때 이러한 동작을 URI를 이용해 동적으로 알려준다는 의미입니다. 각 기능마다 URI를 링크시킴으로써, 동적인 API 제공이 가능하도록 합니다. 

 

 

위와 같이 HATEOAS를 사용하게 되면 누릴 수 있는 장점은 아래와 같습니다. 

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

진짜 REST API를 구현하자

지금까지 Uniform Interface 제약 조건에 대해 알아봤는데, 제약 조건을 모두 만족시키면 REST API라고 할 수 있습니다. 하지만 HAL JSON을 이용하기 전까지는 아직 완벽하지는 않습니다. HAL이란 Hypertext Application Language으로 JSON, XML 코드 내의 외부 리소스에 대한 링크를 추가하기 위한 특별한 데이터 타입입니다. 이러한 HAL은 두 개의 타입을 갖습니다. 

 

1. application/hal+json
2. application/hal+xml

 

이 HAL 타입을 이용한다면 쉽게 HATEOAS를 달성할 수 있습니다. 이런 HAL 타입에서는 두 가지의 특징인 리소스와 링크를 이용하면 됩니다.

 

리소스 : 일반적인 data 필드에 해당합니다.
링크 : 하이퍼미디어로 보통 _links 필드가 링크 필드가 됩니다.

 

아래의 예시를 통해 REST API에 대해 살펴보겠습니다.

 

{
  "data": { // HAL JSON의 리소스 필드
    "id": 1000,
    "name": "게시글 1",
    "content": "HAL JSON을 이용한 예시 JSON"
  },
  "_links": { // HAL JSON의 링크 필드
    "self": {
      "href": "http://localhost:8080/api/article/1000" // 현재 api 주소
    },
    "profile": {
      "href": "http://localhost:8080/docs#query-article" // 해당 api의 문서
    },
    "next": {
      "href": "http://localhost:8080/api/article/1001" // article 의 다음 api 주소
    },
    "prev": {
      "href": "http://localhost:8080/api/article/999" // article의 이전 api 주소
    }
  }
}

 

그렇다면, REST API를 설계할 때, 어떻게 API를 디자인하면 좋을까요? REST API 디자인 가이드에 대해 알아보겠습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

REST API 디자인 가이드

REST API를 설계할 때 아래의 용어들을 알고 활용해야 합니다.

 

 

1. 용어

Resource는 어떤 것의 대표 혹은 객체입니다. 이는 관련 데이터를 갖고 있고, 이를 운용하기 위한 메서드 집합을 가질 수 있습니다. 예를 들어 Animals, schools, employees는 resources이고 delete, add, update는 이 resources들에서 수행되는 operations입니다.
Collections는 resources의 집합입니다. 예를 들어 Companies는 Company resource의 집합입니다.
URL(Uniform Resource Locator)은 어느 resource가 어디에 위치할 수 있고, 어떤 action들이 수행될 수 있는지를 나타내는 경로입니다.

 

 

 

2. API Endpoint

더 이해하기 위해서는 Employees를 가진 Companies에 대한 API를 작성해보겠습니다. /getAllEmployees는 employees의 리스트를 response 하는 API입니다. Company에 관련된 API는 다음과 같은 것이 존재할 수 있습니다.

 

/addNewEmployee
/updateEmployee
/deleteEmployee
/deleteAllEmployees
/promoteEmployee
/promoteAllEmployees

 

그리고 다른 operations를 위해서 아주 많은 API endpoints가 존재할 수 있습니다. 하지만 이는 많은 중복을 포함하고 있고, 이러한 API endpoints는 수가 증가함에 따라서 유지보수가 힘들어집니다. 그럼 이 문제를 해결하기 위해서는 URL은 오직 resources(명사)만 포함해야 하며 동사나 actions를 포함해서는 안 됩니다. API path /addNewEmployee는 action인 addNew를 resource 이름은 Employee와 함께 포함하고 있습니다.

 

그럼 어떻게 해야 API endpoint를 잘 설계할 수 있을까요? /companies endpoint는 action을 포함하지 않는 좋은 예시입니다. 그럼 어떻게 서버에게 해당 companies resource에 대해서 add, delete, update와 같은 actions을 수행하도록 알려줄 수 있을까요? 이는 동사인 HTTP 메서드 (GET, POST, DELETE, PUT 등)가 그 역할을 수행할 수 있습니다.

 

resource는 언제나 API endpoint에서 복수형 이어야 합니다. 그리고 만약 resource의 특정 인스턴스에 접근하고 싶다면 URL에 id를 전달하여 접근할 수 있습니다.

 

method GET path /companies는 companies의 모든 목록을 가져옵니다.
method GET path /companies/34는 company 34의 상세 내용을 가져옵니다.
method DELETE path /companies/34는 company 34를 삭제합니다.

 

몇 가지 다른 사용 사례에서 resource 아래에 여러 개의 resources가 있는 경우, API endpoint는 아래와 같을 수 있습니다. 

 

GET /companies/3/employees는 company 3에 속하는 employees 전체 목록을 가져옵니다.
GET /companies/3/employees/45는 company 3에 속하는 employee 45의 상세 내용을 가져옵니다.
DELETE /companies/3/employees/45는 company 3에 속하는 employee 45를 삭제합니다.
POST /companies는 새로운 company를 생성하고, 생성된 company의 상세 내용을 리턴합니다. 

 

이와 같은 API가 더 일관성 있고 정확합니다. 즉 path는 resources의 복수형을 포함해야 하고, HTTP 메서드는 해당 resource를 대상으로 수행되는 action의 종류를 정의해야 합니다.

 

 

 

 

3. HTTP methods

HTTP는 resources를 대상으로 수행할 수 있는 몇 가지 타입의 methods를 정의해두고 있습니다. URL은 문장이고, resources는 명사이며 HTTP methods는 동사입니다. 

 

주요 HTTP methods는 아래와 같습니다.

 

GET method는 resource로부터 데이터를 요청하며, 어떤 side effect도 발생시켜서는 안 됩니다. 예를 들어 /companies/3/employees는 company 3에 속하는 모든 employees를 리턴합니다.
POST method는 database에 resource를 생성하도록 서버에 요청하며, 대부분 web form 형식으로 제출됩니다. 예를 들어 /companies/3/employees는 company 3에 새로운 employee를 생성합니다. POST는 멱등성(연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질)을 갖지 않으며 여러 번의 request는 각각 다른 영향을 미칩니다. 
PUT method는 resource를 업데이트하거나, 만약 존재하지 않는 경우 생성하도록 서버에 요청합니다. 예를 들어 /companies/3/employees/john 는 company 3에 속하는 employees collection에 john이라는 resource를 업데이트하거나 생성하도록 서버에 요청합니다. PUT은 멱등성을 가지며, 여러 번의 request는 같은 영향을 미칩니다.
DELETE method는 resources 혹은 그것의 인스턴스를 database에서 삭제하도록 요청합니다. 예를 들어 /companies/3/employees/john/ 는 company 3에 속하는 employees collection에서 john이라는 resource를 삭제하도록 서버에 요청합니다.

 

 

 

 

4. HTTP response status codes

API를 통해서 클라이언트가 서버에 request를 발생시키면 클라이언트는 해당 request가 성공, 실패 혹은 request 자체가 잘못되었는지 등의 결과를 얻을 수 있어야 합니다. HTTP status code는 다양한 시나리오에서의 상황을 설명할 수 있는 표준화된 코드입니다. 아래는 HTTP 코드의 주요 카테고리 분류입니다.

 

 

2xx (Success Category)

해당 status code 들은 request가 정상 수신되고 서버를 통해서 성공적으로 수행되었음을 나타냅니다.

  • 200 Ok GET, PUT, POST 성공을 대표하는 표준 HTTP response
  • 201 Created 해당 status code는 새로운 인스턴스 생성 시 리턴되어야 합니다. 예를 들면 POST 메서드를 사용하여 새로운 인스턴스가 생성되면 항상 201 status code를 리턴합니다.
  • 204 No Content는 request가 성공적으로 수행되었으나 아무것도 리턴되지 않음을 의미합니다. 대표적인 예로 DELETE가 있습니다. API DELETE /companies/43/employees/2는 employee 2를 삭제하고 리턴되는 API response body에는 아무런 데이터도 필요하지 않습니다. 이는 시스템에 명시적으로 삭제하도록 요청했기 때문입니다. 만약 employee 2가 데이터베이스에 존재하지 않는 것과 같은 에러가 발생한다면, 2xx Success Category 가 아닌, 4xx Client Error category response code를 리턴하게 됩니다.

 

3xx (Redirection Category)

  • 304 Not Modified는 client가 해당 response를 이미 캐시로 갖고 있음을 의미합니다. 따라서 같은 데이터를 다시 전달할 필요가 없습니다.

 

4xx (Client Error Category)

아래의 status code들은 client가 잘못된 request를 전달했음을 의미합니다.

  • 400 Bad Request는 client의 요청사항을 서버가 이해하지 못해서 request가 정상적으로 수행되지 않았음을 의미합니다.
  • 401 Unauthorized는 client가 resources에 대한 접근 권한이 없으며 필요한 자격을 갖추고 다시 request 해야 함을 의미합니다.
  • 403 Forbidden는 request가 유효하며, client의 권한에도 문제가 없지만 어떠한 이유로 인해서 client가 resource 페이지에 접근할 수 없음을 의미합니다. 예를 들어 때때로 인증된 client가 서버의 디렉터리에 접근할 수 없는 경우가 있습니다.
  • 404 Not Found는 요청된 resource가 현재 사용 불가능 함을 의미합니다.
  • 410 Gone는 요청된 resource가 의도적으로 이동되어 더 이상 사용 불가능 함을 의미합니다.

 

5xx (Server Error Category)

  • 500 Internal Server Error는 request가 유효하지만, 서버에 문제가 발생하여 예상치 못한 조건을 제공하도록 요청받았음을 의미합니다.
  • 503 Service Unavailable는 서버가 다운되거나 request를 처리할 수 없음을 의미합니다. 대부분 서버 점검 시에 발생합니다.

 

 

 

 

5. 필드 네이밍 컨벤션

원하는 네이밍 컨벤션을 사용할 수 있지만, 애플리케이션 전체에 걸쳐서 일관성을 갖는 것이 중요합니다. 만약 request body 혹은 response type이 JSON이라면 일관성을 위해서 카멜 케이스 규칙을 따르는 것이 좋습니다.

 

 

 

 

6. 검색, 정렬, 필터링, 페이지 네이션

이러한 모든 작업은 하나의 데이터 집합에 대한 쿼리일 뿐입니다. 이 같은 action을 처리하기 위한 별도의 API set은 존재하지 않습니다. 다만 API의 GET 메서드에 쿼리 파라미터를 추가할 필요가 있습니다. 몇 가지 예시를 통해서 해당 action 들을 어떻게 구현할 수 있는지 살펴보겠습니다.

  • Sorting 정렬된 companies 리스트를 원하는 경우, GET /companies endpoint는 여러 개의 정렬 매개변수를 쿼리에서 받아야 합니다. 예를 들어 GET /companies? sort=rank_asc는 rank 오름차순으로 companies를 정렬해야 합니다.
  • Filtering 데이터셋 필터링을 위해서 쿼리 매개변수를 통해 다양한 조건을 전달할 수 있습니다. 예를 들어 GET /companies? category=banking&location=india는 india에 위치하는 banking 카테고리의 companies를 필터링해야 합니다.
  • Searching companies list 중에서 이름을 검색하려면 API endpoint는 GET /companies? search=Digital Mckinsey와 같아야 합니다.
  • Pagination 데이터셋이 너무 큰 경우, 데이터를 작은 덩어리로 나눔으로써 퍼포먼스를 향상하고 response 핸들링을 좀 더 편하게 할 수 있습니다. 예를 들어 GET /companies? page=23은 companies 리스트의 23번째 페이지를 의미합니다.

만약 GET 메서드에 많은 쿼리 매개변수를 전달하여 URI가 너무 길어진다면 서버는 414 URI Too long HTTP status를 응답할 것입니다. 이런 경우에는 POST 메서드의 request body를 통해서도 매개변수를 전달할 수 있습니다.

 

 

 

7. Versioning

만약 API가 여러 곳에서 사용되고 있을 때 일부 변경 사항으로 API를 업그레이드하면, 기존의 API를 사용하는 제품이나 서비스에 문제가 발생할 수 있습니다. 예를 들어 http://api.yourservice.com/v1/companies/34/employees처럼 경로에 API의 버전을 포함하는 것은 좋은 예시입니다. 만약 주요 업데이트가 있는 경우에는 v2, v1.x.x 와 같은 새로운 API set을 위한 이름을 사용할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

마치며

지금 내가 알고 있다고 생각한 개념과 내용을 정말 알고 있는 것이 맞는 것인지 스스로에게 의문을 던져보고, 만약 개념을 모르고 있다면, 내가 남들에게 설명할 수 있을 때까지 제대로 공부해야겠다고 생각했습니다. 만약 타인에게 내가 공부한 개념을 제대로 설명할 수 있는 날이 오길 바라며. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

출처

 

[Network] REST란? REST API란? RESTful이란? - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

 

그런 REST API로 괜찮은가?

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

velog.io

 

(번역) RESTful API Designing guidelines — The best practices · 초보몽키의 개발공부로그

(번역) RESTful API Designing guidelines — The best practices 26 Nov 2017 | RESTful API Designing guidelines — The best practices 번역글 입니다. Facebook, Google, Github, Netflix와 같은 거대한 테크기업은 API를 통해서 개

wayhome25.github.io

 

[Hateoas] Hateoas(헤이티오스) 란 ( + REST API란 )

Hateoas에 대한 정의 REST API에 대한 정의 Hateoas 사용 예시 Hateoas에 대한 정의 Hypermedia As The Engine Of Application State의 약자로, 기본적인 아이디어는 하이퍼미디어를 애플리케이션의 상태를 관..

joomn11.tistory.com

 

HATEOAS

HATEOAS란 HATEOAS(Hypermedia As The Engine Of Application State)란 REST Api를 사용하는 클라이언트가 전적으로 서버와 동적인 상호작용이 가능하도록 하는 것을 의미합니다. 이러한 방법은 클라이언트가 서버..

kchanguk.tistory.com

 

[REST] REST란 무엇인가? REST맛보기

[REST] REST란 무엇인가? REST맛보기 ■ REST란 무엇인가? REST는 Representational State Transfer의 약자로 월드와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍쳐의 한 형식이다. REST란

gangnam-americano.tistory.com