1. REST API(Representational State Transfer API)
웹에서 사용되는 데이터나 자원(Resource)를 HTTP URI로 표현하고 HTTP 프로토콜을 통해 요청과 응답을 정의하는 방식이다. 로이 필딩(Roy Fielding)이 웹(HTTP)의 장접을 최대한 활용할 수 있는 아키텍처로서 논문에서 제시했다.
레오나르드 리차드슨(Leonard Richardson)은 로이 필딩이 논문에서 제시한 REST 방법론을 실용적으로 적용하기 위해 REST 성숙도 모델을 만들었다.
로이 필딩은 이 모델의 모든 단계를 충적해야 REST API라고 부를 수 있다고 주장했지만 실제로 엄밀히 3단계까지 지키기는 어렵기 때문에 2단계까지만 적용해도 좋은 API 디자인이라고 볼 수 있고, 이런 경우를 HTTP API라고 부른다.
1) REST 성숙도 모델
(1) 0단계
REST 성숙도 모델에 따르면 0단계에서는 단순히 HTTP 프로토콜을 사용하기만 해도 된다.
물론 이 경우, 해당 API를 REST API라고 하지는 않는다. 0단계는 REST API를 작성하기 위한 기본 단계이다.
예를 들어, 병원에 예약을 하려고 한다고 가정해보자.
그러면 우리는 먼저 주치의의 예약 가능한 시간을 확인하고 특정 시간에 예약하려고 할것이다.
요청 내용 | 요청(Requests) | 응답(Responses) |
예약가능한 시간 확인 | POST /appointment HTTP/1.1 [헤더 생략] { "date" : "2023-02-01", "doctor" : "김명의" } |
HTTP/1.1 200 OK [헤더 생략] { "slots" : [ {"doctor" : "김명의", "start": "09:00", "end" : "12:00}, {"doctor" : "김명의", "start": "14:00", "end" : "18:00} ] } |
특정한 시간에 예약하기 | POST /appointment HTTP/1.1 [헤더 생략] { "doctor" : "김명의", "start" : "14:00", "end" : "15:00", "patient" : "최환자" } |
HTTP/1.1 200 OK [헤더 생략] |
(2) 1단계
1단계에서는 개별 리소스(Resource)와의 통신을 준수해야 한다.
모든 자원은 개별 리소스에 맞는 엔드포인트(Endpoint)를 사용해야하며, 요청하고 받는 자원에 대한 정보를 응답으로 전달해야한다. 엔드포인트 작성시에는 동사, HTTP 메서드, 또는 어떠한 행위에 대한 단어 사용은 지양하고, 리소스에 집중해 명사형의 단어로 작성하는 것이 바람직하다.
또한 요청에 따른 응답으로 리소스를 전달할 때도 사용한 리소스에 대한 정보와 함께 리소스 사용의 성공/실패 여부를 함께 반환해야 한다.
요청 내용 | 요청(Requests) | 응답(Responses) |
예약가능한 시간 확인 | POST /doctors/김명의 HTTP/1.1 [헤더 생략] { "date" : "2023-02-01" } |
HTTP/1.1 200 OK [헤더 생략] { "slots" : [ {"id": 1, "doctor" : "김명의", "start": "09:00", "end" : "12:00}, {"id" : 2, "doctor" : "김명의", "start": "14:00", "end" : "18:00} ] } |
특정한 시간에 예약하기 | POST /slots/2 HTTP/1.1 [헤더 생략] { "patient" : "최환자" } |
HTTP/1.1 200 OK [헤더 생략] { "appointment" : { "slot" : {"id": 2, "doctor": "김명의", ...}, "patient" : "최환자" } } // 또는 HTTP/1.1 409 conflict [헤더 생략] { "appointmentFailure" : { "slot" : {"id": 2, "doctor": "김명의", ...}, "patient" : "최환자", "reason" : "이미 예약된 시간입니다" } } |
이전 예시에서는 모두 /appointment를 엔드포인트로 사용하였다. 하지만 1단계인 개별 리소스와의 통신을 준수하기 위해 엔드포인트를 변경한다면 위와 같이 변경할 수 있을 것이다. 이렇게 적절한 엔드포인트를 작성하는것이 중요하다.
(3) 2단계
2단계 에서는 CRUD에 맞게 적절한 HTTP 메서드를 사용하는 것에 중점을 둔다.
예를들어 조회(READ)시에는 GET 메서드를 사용하고, GET 메서드는 body를 가지지 않기 때문에 필요에 따라 query parameter를 사용해서 필요한 리소스를 전달한다.
생성(CREATE)의 경우, POST 메서드를 사용하여 요청을 보낸다. 이 경우 새롭게 생성된 리소스가 응답으로 보내지기 때문에 응답 코드는 201 Created로 명확하게 작성되어야 한다. 또한 관련 리소스를 클라이언트가 Location 헤더에 작성된 URI를 통해 확인할 수 있다면 완벽하게 REST 성숙도 모델의 2단계를 충족했다고 볼 수 있다.
- GET은 서버의 데이터를 변화시키지 않는 요청에 사용한다.
- POST는 요청마다 새로운 리소스를 생성하고, PUT은 요청마다 같은 리소스를 반환한다.
PUT처럼 매 요청마다 같은 리소스를 반환하는 특징을 멱등(idempotent)하다고 한다. 따라서 POST와 PUT은 구분하여 사용하여야 한다. - PUT은 교체, PATCH는 수정의 용도로 사용한다.
요청 내용 | 요청(Requests) | 응답(Responses) |
예약가능한 시간 확인 | GET /doctors/김명의/slots?date=2023-02-01 /HTTP/1.1 [헤더 생략] { "date" : "2023-02-01", "doctor" : "김명의" } |
HTTP/1.1 200 OK [헤더 생략] { "slots" : [ {"id": 1, "doctor" : "김명의", ...}, {"id" : 2, "doctor" : "김명의", ...} ] } |
특정한 시간에 예약하기 | POST /slots/2 HTTP/1.1 [헤더 생략] { "patient" : "최환자" } |
HTTP/1.1 201 Created Location: slots/2/appointment [헤더 생략] { "appointment" : { "slot" : {"id": 2, "doctor": "김명의", ...}, "patient" : "최환자" } } |
💡 멱등성(idempotent)
어떤 HTTP 메서드가 동일한 요청을 한번 보내는 것과 여러번 연속으로 보내는 것이 같은 효과를 지니고 서버의 상태도 동일하게 남을때 그것을 멱등성을 가졌다고 한다. 멱등성을 가진 메서드는 통계 기록 등을 제외한 side effect가 있어서는 안된다. 즉, 요청에 대한 서버의 상태가 항상 같다는 것이 중요하다. 모든 안전한 메서드는 멱등성을 가진다. 올바르게 구현한 경우 GET, HEAD, OPTIONS, PUT, DELETE 메서드는 멱등성을 가지고 POST 메서드는 그렇지 않다.
- GET
서버에 존재하는 리소스를 읽어오기만 하기 때문에 여러번 수행되어도 결과값이 변하지 않는다. HEAD와 OPTIONS도 조회와 관련된 메서드이기 때문에 멱등성을 갖고있다고 볼수있다. - PUT
서버에 존재하는 리소스를 요청에 담긴 내용대로 통째로 대체하기때문에 올바르게 구현했다면 여러번 수행되어도 결과값은 변하지 않는다. - DELETE
존재하는 데이터를 삭제한 결과와 이미 존재하지 않는 결과를 삭제하려는 시도에 대한 응답코드는 서로 다를것이다. (200 OK / 404 Not Found) 그러나 서버의 상태 자체는 변하지 않음으로 올바르게 구현되었다면 여러번 수행되어도 멱등성이 보장된다.
(4) 3단계
마지막 단계인 3단계는 HATEOAS(Hypermedia As The Engine Of Application State)라는 약어로 표현되는 하이퍼미디어 컨트롤을 적용한다. 3단계의 요청은 2단계와 동일하고, 응답의 경우 리소스의 URI를 포함한 링크 요소를 삽입하여 작성한다.
이때 응답에 들어가게 되는 링크 요소는 응답을 받은 다음 할 수 있는 액션들을 위해 많은 하이퍼미디어 컨트롤을 포함한다. 응답 내에 새로운 링크를 넣어 새로운 기능에 접근할 수 있도록 하는것이 3단계의 핵심이다.
요청 내용 | 요청(Requests) | 응답(Responses) |
예약가능한 시간 확인 | GET /doctors/김명의/slots?date=2023-02-01 /HTTP/1.1 [헤더 생략] { "date" : "2023-02-01", "doctor" : "김명의" } |
HTTP/1.1 200 OK [헤더 생략] { "slots" : [ {"id": 1, "doctor" : "김명의", ...}, {"id" : 2, "doctor" : "김명의", ...} ], "links" : { "appointment" : { "href" : http://localhost:8080/slots/2, "method" : "POST" } }, } |
특정한 시간에 예약하기 | POST /slots/2 HTTP/1.1 [헤더 생략] { "patient" : "최환자" } |
HTTP/1.1 201 Created Location: slots/2/appointment [헤더 생략] { "appointment" : { "slot" : {"id": 2, "doctor": "김명의", ...}, "patient" : "최환자" }, "links" : { "self" : { "href" : http://localhost:8080/slots/2, "method" : "GET" }, "cancel" : { "href" : http://localhost:8080/slots/2/cancel, "method" : "DELETE" } }, } |
2) Open API와 API Key
(1) Open API
Open API는 글자 그대로 누구에게나 열려있는 API이다. 하지만 무제한으로 이용할 수 있다는 뜻은 아니다.
각 API마다 정해진 이용 수칙이 있고 가격이나 정보의 제한 등 제한 사항이 있을 수 있다.
(2) API Key
API Key는 API를 이용하기 위해 발급받는 열쇠라고 생각 할 수 있다. API Key가 필요한 경우 서버에서는 로그인한 이용자에게 자원에 접근할 수 있는 권한을 API Key의 형태로 제공하고 데이터를 요청할때 API Key를 같이 전달해야 원하는 응답을 받을 수 있다.
******************************************
요약 & 일일회고
- REST API는 웹에서 사용되는 리소스들을 URI로 표현하고 HTTP 프로토콜을 통해 요청과 응답을 정의하는 방식이다.
- REST 성숙도 모델은 0단계부터 3단계까지의 총 4가지 단계가 있다. 0단계는 HTTP 프로토콜을 사용하는 것이다. 0단계는 REST API를 사용하기 위한 기초 단계로서 단지 HTTP 프로토콜을 사용했다고 해서 REST API를 사용했다고 하지는 않는다. 1단계는 개별 리소스와의 통신을 준수하여 적절한 엔드포인트를 사용하고 요청하고 받는 자원에 대한 정보를 응답으로 전달하는 것이다. 엔드포인트는 가급적 명사형을 사용하도록 한다. 2단계는 CRUD에 맞게 적절한 HTTP 메서드를 사용하는 것이다. 조회의 경우는 GET, 새롭게 리소스를 생성할 경우는 POST, 삭제할때는 DELETE 등의 메서드를 사용한다. GET, PUT, HEADER, DELETE 등은 올바르게 작성할 경우 멱동성을 가지지만 POST는 그렇지 않다. 멱동성이란, 요청을 여러번 해도 같은 리소스를 반환하며 서버의 상태가 변하지 않는것이다. POST는 요청시 새로운 리소스를 생성하여 서버상태를 변화시키기 때문에 멱동성을 갖지 않는다고 할수있다.
- OPEN API는 누구에게나 열려있는 API이다. 하지만 무제한으로 이용할 수 있는 것은 아니고, 각 API마다 정해진 이용 수칙이 있고 가격이나 정보의 제한 등 제한 사항이 있을 수 있다.
- API Key는 API를 사용하기 위해 발급받는 열쇠이다. API를 사용하기 위해 API Key가 필요한 경우 데이터 요청과 함께 사용해야 한다.
***
REST API 어렵다... 흑흑
그냥 아직 HTTP 요청/응답 메시지를 잘 알지 못해서 더 어려운것 같다.
내일 과제 하면서 같이 블로깅 하고 정리해봐야지.
연습하다보면 나아질거야
******************************************
참고 링크
https://meetup.nhncloud.com/posts/92
https://www.ibm.com/kr-ko/cloud/learn/rest-apis
https://aws.amazon.com/ko/what-is/restful-api/
https://developer.mozilla.org/ko/docs/Glossary/REST
https://developer.mozilla.org/ko/docs/Glossary/Idempotent
https://hudi.blog/http-method-idempotent/
https://martinfowler.com/articles/richardsonMaturityModel.html
'study > TIL' 카테고리의 다른 글
230202 - React 데이터 흐름, Effect Hook (0) | 2023.02.02 |
---|---|
230201 - REST API 복습, Postman 사용하기 (0) | 2023.02.01 |
23.01.30 - 네트워크 기초 지식 (0) | 2023.01.30 |
23.01.26 - React Props, State, 이벤트 핸들링, controlled component, 데이터 흐름 (0) | 2023.01.26 |
23.01.25 - React SPA, React Router (2) | 2023.01.25 |