REST API 문서 이해하기
REST API
REST API 란?
REST는 Representational State Transfer의 약자
클라이언트와 서버가 HTTP 통신으로 요청과 응답을 할 때, 제대로 보내고 받을 수 있는 일종의 규약이 존재
→ REST API
→ 웹에서 사용되는 데이터나 자원(Resource)을 HTTP URI로 표현하고, HTTP 프로토콜을 통해 요청과 응답을 정의하는 방식
API는 클라이언트 - 서버 간의 메뉴판과 비슷한데, 서로가 잘 알아볼 수 있도록 작성하는 것이 중요하다
좋은 REST API를 디자인 하는 방법: 리차드슨의 REST 성숙도 모델(RMM)
REST API를 잘 적용하기 위한 4단계 모델
→ REST 성숙도 모델은 총 4단계(0~3단계)로 나뉜다
3단계 : HATEOAS 원칙 준수
-------------------------------
2단계: HTTP 메소드 원칙 준수
-------------------------------
1단계: 개별 리소스와의 통신 준수
-------------------------------
0단계: HTTP 사용
-------------------------------
<Richardson 성숙도 모델>
이 3단계를 모두 충족해야 REST API 라고 할 수 있다고 하지만(창시자 주장), 실제로 3단계까지 엄밀하게 지키기 어렵기 때문에 2단계까지만 충족해도 좋은 API 디자인이라고 볼 수 있다
→ 이 경우 HTTP API 라고 부르기도 한다
REST 성숙도 모델 – 0단계
0단계에서는 단순히HTTP 프로토콜을 사용하기만 하면 된다. 해당 API는 아직 REST API라고 할 수는 없으며, 기본 단계라 보면 됨
김사부라는 의사의 예약 가능 시간을 확인하고, 특정 시간에 예약하는 병원 예약을 예로 보면,
요청 내용 요청 응답
============================================================================
예약 가능 POST /appointment HTTP/1.1 200 ok
시간 확인 HTTP/1.1 [헤더 생략]
[헤더 생략]
{ {
“date”: “2021-10-20” json 형식 내용 출력
“doctor”: “김사부” }
}
-----------------------------------------------------------------------------
POST /appointment HTTP/1.1 200 ok
특정 시간 HTTP/1.1 [헤더 생략]
예약 [헤더 생략]
{
json 형식 내용
}
REST 성숙도 모델 – 1단계
개별 리소스와의 통신 준수의 의미
→ 모든 자원은 개별 리소스에 맞는 엔드포인트(Endpoint)를 사용해야 한다는 것과 요청하고 받은 자원에 대한 정보를 응답으로 전달해야 한다는 것
위의 예시로 보면, 앞서 0단계에서는 모든 요청에서 엔드포인트로 /appointment 를 사용하였다. 그러나 1단계에서는 요청하는 리소스가 무엇인지에 따라 다른 엔드포인트로 구분해 사용 해야 한다.
요청 내용 요청 응답
============================================================================
예약 가능 POST /doctors/김사부 HTTP/1.1 200 ok
시간 확인 HTTP/1.1 [헤더 생략]
[헤더 생략]
{ {
“slots” : [
“date”: “2021-10-20” json 형식 내용 출력
“doctor”: “김사부” ]}
}
-----------------------------------------------------------------------------
POST /slots/111 HTTP/1.1 200 ok
특정 시간 HTTP/1.1 [헤더 생략]
예약 [헤더 생략]
{ {
json 형식 내용 “appointment”: {
} “slot”:{ 내용},
“patient”: “박씨”
}
}
예시에서 예약 가능한 시간 확인 이라는 요청의 응답으로 받는 자원(리소스)는 김사부의 예약 가능한 시간대이다
→ /doctors/김사부 라는 엔드포인트 사용
특정 시간에 예약 하는 경우에도 slots/111 라는 실제 변경되는 리소스 부분의 엔드포인트를 사용
→ 엔드포인트 작성 시에는 동사, HTTP 메소드, 혹은 어떤 행위에 대한 단어 사용은 지양하고, 리소스에 집중해 명사 형태의 단어로 작성하는 것이 바람직하다(동사 등은 사용x)
그리고, 요청에 따른 응답으로 리소스를 전달할 때, 사용한 리소스에 대한 정보와 함께 리소스 사용에 대한 성공/실패 여부를 반환해줘야 한다
→ 즉 실패 시에도 실패 여부를 포함한 응답을 받아야 한다는 것
ex) 응답 부분의 예시
응답
==============================================
HTTP/1.1 409 Conflict
[헤더 생략]
{
“appointmentFail”: {
“slot”:{“id”: 111, “doctor”: “김사부” },
“patient”: “박씨”,
“reason”: “해당 시간은 예약 마감”
}
}
REST 성숙도 모델 – 2단계
CRUD에 맞게 적절한 HTTP 메소드를 사용하는데 중점
앞서 작성한 예시를 살펴 보면,
예약 가능한 시간 확인은 조회(READ) 이므로, POST → GET 메소드 사용해야 하며, 이때 GET 메소드는 body를 가지지 않으므로 쿼리 파라미터를 이용하여 필요한 리소스를 전달해야 한다
ex) 해당 부분 변경 예시
요청
================================================
GET /doctors/김사부/slots?date=2021-10-20 HTTP/1.1
[헤더 생략]
특정 시간에 예약하는 것은 생성(CREATE)이므로, POST 메소드를 사용하여 요청하면 된다
그런데, 2단계에서는 POST 요청에 대한 응답이 어떻게 반환되는지도 중요하다
이 경우의 응답은 새롭게 생성된 리소스를 보여주므로, 응답 코드 200 OK → 201 Created 로 명확히 해야 하며, 관련 리소스를 클라이언트가 Location 헤더에 작성된 URI를 통해 확인 할 수 있도록 해야 완벽하게 REST 성숙도 모델의 2단계를 충족한 것이다
ex) 해당 부분 변경 예시
응답
===============================
HTTP/1.1 201 Created
Location: slots/111/appointment
[헤더 생략]
{
이하 동일
}
메소드 사용시에도 일정 규칙이 있다
* GET: 서버의 데이터를 변화시키지 않는 요청에 사용
* POST: 요청마다 새로운 리소스를 생성함 → 멱등성 X
* PUT: 요청마다 같은 리소스를 반환함 → 멱등성 O
→ 매 요청마다 같은 리소스를 반환하는 특징: 멱등성(idempotent)
→ PATCH와 비슷해보이나, `교체`의 용도로 주로 사용
* PATCH: PUT과 비슷해 보이나, `수정`의 용도로 주로 사용
* DELETE: 특정 리소스 삭제시 사용
→ DELETE에 본문(body)을 실어서 전달(요청)할 수도 있지만, 일반적으로 엔드포인트에 리소스를 명시하는 편이 낫다
ex) DELETE /articles/11
대체로 2단계까지 적용을 하면 잘 작성된 API라 볼 수 있다
(3단계까지 무조건적으로 모두 적용해야 하는 것은 아님)
REST 성숙도 모델 – 3단계
HATEOAS(Hypertext As The Engine Of Application State)라는 약어로 표현되는 하이퍼미디어 컨트롤을 적용하는 단계
3단계의 요청은 2단계와 동일하지만, 응답에는 리소스의 URI를 포함한 링크 요소를 삽입하여 작성한다는 것이 다름
이때 응답에 들어가게 되는 링크 요소는 응답을 받은 다음에 할 수 있는 다양한 액션들을 위해 많은 하이퍼미디어 컨트롤을 포함하고 있다
ex) 해당 부분 변경 예시
응답
=================================================================
HTTP/1.1 200 OK
예약 가능 [헤더 생략]
시간 확인
{
“slots”: [
{“id”:111, “doctor”: “김사부” },
],
“links”: {
“appointment”: {
“href”: “http://특정주소/slots/111”,
“method”: “POST”
}
}
}
-------------------------------------------------------------------
특정 시간 HTTP/1.1 201 Created
예약 Location: slots/111/appointment
[헤더 생략]
{
“appointment”: {
“slot”: {“id”: 111, “doctor”: “김사부”, …},
“patient”: “박씨”,
},
“links”: {
“self”: {
“href”: “http://특정주소/slot/111”,
“method”: “GET”
},
“cancel”: {
“href”:http://특정주소/slot/111/cancel”,
“method”: “DELETE”
}
}
}
위의 예시와 같이 응답하는 리소스의 URI를 포함한 링크 요소로
예약 가능 시간 확인 후 그 시간대에 예약을 할 수 있는 링크 삽입,
특정 시간대에 예약을 완료한 후, 그 예약을 다시 확인 및 취소할 수 있도록 링크 삽입
→ 이렇게 응답 내에 새로운 링크를 넣어 새로운 기능에 접근할 수 있도록 하는 것이 3단계의 중요 포인트
링크들은 더 쉽고, 효율적이게 리소스와 기능에 접근할 수 있도록 해주는 트리거가 된다
OPEN API 와 API Key
OPEN API
정부에서 제공하는 공공 데이터가 OPEN API의 형태이다
→ 글자 그대로 누구에게나 열려 있는 API 라는 뜻
그러나, 무제한으로 이용 할 수 있다는 것은 아니다
→ 기관이나 API 마다 정해진 이용 수칙에 따른 제한 사항이 존재할 수 있음
대표적인 OPEN API의 예: Open Weather Map(https://openweathermap.org/api)
→ 날씨 API 로, 제한적으로 무료의 API 제공 및 데이터를 JSON 형태로 응답함
API Key
API를 이용하기 위해서는 API Key가 필요하다
→ 서버의 문을 여는 열쇠
클라이언트-서버 간 요청 응답이 발생하려면, 즉 서버가 존재하고 운용되어야 한다는 것인데
→ 비용 발생
그러므로 보통, 로그인된 이용자에게만 자원에 접근할 권한을 API Key의 형태로 제공하고,
데이터를 요청할 때 API Key를 같이 전달해야만 원하는 응답을 받을 수 있도록 한다
Postman
Postman 사용법
HTTP API 테스트 도구
웹 개발에서 사용하는 대표적인 클라이언트: 브라우저
→ 브라우저로 서버에 다양한 HTTP 요청을 보낼 수 있지만, 주로 웹 페이지를 받아오는 GET 요청에 사용함
테스트를 위해 GET이 아닌 다른 요청을 보내려면, 개발자 도구의 콘솔 창에서 내장함수 fetch 를 사용
매번 코드 작성할 수는 있지만 너무 번거롭다. 그렇다면?
→ API 테스트 도구: 클라이언트 입장에서 서버 API를 테스트하거나, API 만드는 과정에서도 유용
대표적인 HTTP API 테스트 도구
[CLI]
* curl(대부분의 리눅스 환경에서 내장되어 있음)
* wuzz
[GUI]
* Postman
* Insomnia
아래에서는 Postman을 통해 HTTP API TEST를 진행해 보자
Postman 사용하기
이미 만들어져 있는 API 서버가 주어졌다고 가정
→ HTTP로 소통하려면 API 서버의 endpoint 가 URL로 주어져야 한다
가령 http://특정주소:3000/kimblabla/messages 와 같이 입력하면 됨
GET 요청은 본문(body)가 없으므로 엔드포인트로 조회(read)하거나 추가적인 파라미터를 사용하여 조회하면 된다
→ 응답으로 status: 200 OK 이면 정상
POST 요청은 본문(body)가 들어가야 하므로 body 카테고리를 선택한 후 raw 타입(라디오버튼), JSON 형식(토글 박스)을 선택하여 JSON 형식으로 작성해 보자
→ JSON 형식으로 보낼 때는 raw를 선택해야 한다
이 과정은 HTTP 요청 헤더에 다음과 같이 작성하는 것과 동일하다
Content-Type: application/json
// HTTP 요청 헤더에 전송할 데이터 타입을 입력한 것
선택 후에 본문 내용을 json 형식에 맞게 작성하여 POST 요청하면 된다
응답 살펴보기
요청이 끝나지 않는 경우
일반적으로 서버가 요청에 대한 응답을 하지 않는 경우, 요청이 끝나지 않는다
→ 서버의 문제
→ 만약 우리가 서버를 만들고 있는 중이었다면, 응답 처리를 했는지 확인 해보자: timeout 응답일 것이다
기대한 응답이 아닌 경우
결과에 아무 것도 나오지 않거나, 기대했던 값(응답)이 아닌 경우, HTTP 응답 코드를 확인해 볼 것
ex) Status: 400 Bad Request → 잘못된 요청을 한 경우
Postman으로 날씨 받아오기
Postman with Open API
Open Weather Map 의 API Docs를 보면서 open API를 사용하여 거주지의 날씨를 요청하고, 응답을 받아 보자
https://openweathermap.org 에 접속하여 회원가입 후 로그인, 메일 인증 절차를 진행하면,API Keys 탭에 기본 Default API key 가 발급된 것을 확인 가능
→ 단 유효한 키가 되기까지 약 30분이 걸린다 (그 전 까지는 사용하려고 하면 Invaild key로 뜬다)
원하는 API를 탐색하여, API Doc 을 보고 그 형식에 따라서 API key 등 파라미터를 수정해서 URI에 넣으면 브라우저 및 Postman에서 확인 가능하다(Get 메소드 이용)
REST API 디자인을 위한 5가지 가이드라인
Resources(자원; URIs)
- 동사(동어) 반복을 하지 않도록 작성
GET /users/1234 (O)
GET /users/get/1234 (X)
- URI case
작성할때 spinal-case 쓰기
camelCase //자바스크립트
PacelCase // Class
snake_case // 데이터베이스
spinal-case //URI 작성 시
HTTP methods
HTTP Method 멱등성 안전함(safety)
============================================
GET YES YES
HEAD YES YES
PUT YES NO
DELETE YES NO
POST NO NO
PATCH NO NO
--------------------------------------------
PUT: 해당 자원(데이터)를 완전히 바꾼다 (멱등성o)
PATCH: '' 를 조금 바꾼다 (멱등성x)
HTTP headers
GET POST 등 요청했을때 header 부분
Query parameters
Paging(페이지네이션)
- 페이지를 구분해서 한번에(1페이지) 몇개의 검색 결과가 나오는지 설정
ex) ?page=1&per_page=30
Filtering
- 필터링하고 싶은 부분 설정(close, open)
ex) ?status=open // open된 부분만 가져옴
Sorting
- 정렬 관련 설정
ex) ?direction=desc
Searching
- 검색 관련 파라미터(q)
ex) ?q=javascript
Status Codes
200대: OK
300대: 반복된 요청
400대: 너의 실수(클라이언트)
500대: 내 실수(서버)
'SE Bootcamp 내용 정리' 카테고리의 다른 글
| react - 데이터 흐름의 이해와 비동기 요청 처리 보충 내용 (0) | 2021.10.21 |
|---|---|
| react - 데이터 흐름의 이해와 비동기 요청 처리 1 (0) | 2021.10.21 |
| http/네트워크 - 기초 (0) | 2021.10.18 |
| js/node - 비동기 2 (0) | 2021.10.15 |
| js/node - 비동기 1 (0) | 2021.10.15 |
