● REST API가 생기게 된 배경
REST API는 왜 생기게 되었을까요?
우리가 흔히 아는 API에 URI를 적어 데이터를 요청하고 받아올 수 있었습니다. 예전에는 URI에서 동사를 사용하는 것이 일반적이었습니다.
GET getUserId/1234
GET readMovie_avatar
POST plzpostmypretty_blog/user/12346
위는 나쁜 예시로, 이전에는 동사와 명사를 섞어 URI를 만들었기 때문에 URI가 지저분하고 알아보기가 쉽지 않았습니다. (심각했음)
이를 보다 못한 '로이 필딩'이 REST API라는 논문을 써 발표했고, 세상에 주목받기 시작했습니다.
그렇다면 REST API란 무엇일까요?
REST API에서 REST는 (Representational State Transfer)의 약자로, 웹에서 사용되는 자원이나 데이터를 HTT URI로 표현하고 HTTP 프로토콜을 통해 요청과 응답을 받아오는 방식을 이야기합니다.
REST API설계 시, 가장 중요한 2가지는 아래와 같습니다.
- 첫 번째, URI는 정보의 자원을 표현해야한다.
- 두 번째, 자원에 대한 행위는 HTTP Method로 표현한다. (GET, POST, DELETE, PUT)로 표현한다.
우리가 도서관에서 책을 찾을 때, 책의 이름을 보고 찾듯이 URI에는 자원의 '정보' 만 들어가있고, 그것을 읽고 쓰고 지우고 수정하는 행위는 HTTP 메서드로 써야한다는 것이죠.
● REST 성숙도 모델
레오나르도 리차드슨은 REST 방법론을 더 실용적으로 쓰기 위해 REST 성숙도 모델을 만들었습니다. 그렇다면 REST API 성숙도 모델이 무엇인지 함 봐뵤져
- 0단계 HTTP 사용
0단계에는 단순히 HTTP 프로토콜만 사용한 모습도 0단계입니다. 하나의 End-point만 사용하기 때문에 HTTP Method도 반드시 POST가 됩니다. 서버에 데이터를 제출하는 데 사용할 수 있는 가장 일반적인 HTTP 방식이기 때문입니다. (이전에는 form태그로 제출을 했었기 때문에 가장 원초적인 방법을 보여준다고 생각하면 될 것 같다.)
Requset
POST /api/user
{
"function": "getUser",
"arguments" [
"1"
]
}
Response
HTTP/1.1 200 OK
{
"result" {
"id": "1"
"name": "honey",
}
}
CRUD
CREATE : POST /api/user
READ : POST /api/user
UPDATE : POST /api/user
DELETE : POST /api/user
- 1단계 : 개별리소스와 통신 준수
Level 1은 리소스 개념을 도입합니다. 모든 요청을 하나의 End-point로 보내는 것이 아니라 개별 리소스와 통신하게 됩니다.
HTTP Method는 GET과 POST만 사용하고 StatusCode는 무조건 200으로 전달한다. 헤더에 Content-Type이나 Cache 관련 정보도 제공하지 않습니다.
Request
POST /api/users/create
{
"name": "honey"
}
Response
HTTP/1.1 200 OK
{
"result" {
"error": "already exist member"
}
}
CRUD
CREATE : POST /api/users/create
READ : GET /api/users/1
UPDATE : POST /api/users/update
DELETE : POST /api/users/remove/1
- 2단계 HTTP 메서드 원칙 준수
2단계는 4가지 HTTP Method를 사용해서 CRUD를 표현하고 StatusCode도 활용하여 반환합니다.
URI에는 행위(Action)가 포함되지 않고 HTTP Method로 표현합니다. GET은 매번 같은 결과를 반환하고, 헤더에 Content-Type을 제공하고 멱등성을 보장하는 GET의 경우 캐시가 적용됩니다. 현재 가장 많은 REST API가 이 단계에 해당한다고 합니다.
매 요청마다 같은 리소스를 반환하는 특징을 멱등(idempotent)하다고 합니다. 그렇기 때문에 멱등성을 가지는 메서드 PUT과 그렇지 않은 메서드POST는 구분하여 사용해야 합니다.
(GET, DELETE, PUT은 멱등성을 보장한다. but POST는 아니다..)
Request
POST /api/users
{
"name": "honey"
}
Response
HTTP/1.1 201 Created
Content-Type: application/json
{
"result" {
"id": "1",
"name": "honey"
}
}
CRUD
CREATE : POST /api/users
READ : GET /api/users/1
UPDATE : PUT /api/users/1
DELETE : DELETE /api/users/1
- 3단계 HATEOAS(Hypermedia As The Engine Of Application State) 원칙 준수
마지막 단계인 Level 3이다. API 서비스의 모든 End-point를 최초 진입점이 되는 URI를 통해 Hypertext Link 형태로 제공한다. 추가적으로 다음 Request에 필요한 End-point까지 제공을 한다.
Request
GET /api/
Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"/api/users",
"/api/users/{userId}",
"/api/products",
"/api/..."
}
Request
GET api/users/1
Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"result" {
"id": "1",
"name": "honey",
"_links": {
"self" : {
"href" : "https:/api/users/1"
},
"update" : {
"href" : "https:/api/users/1"
},
"list" : {
"href" : "https:/api/users/"
},
}
}