본문 바로가기
Web

REST API 자세히 알아보기

by 치범 2022. 1. 24.

1. REST(RESTful)란?

REST(Representational State Transfer)는 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식이다. 엄격한 의미로 REST는 네트워크 아키텍처 원리의 모음이다. 여기서 '네트워크 아키텍처 원리'란 자원을 정의하고 자원에 대한 주소를 지정하는 방법 전반을 일컫는다.

요약하자면, 자원을 표현하여 그 자원의 상태 정보를 전달하는데 쓰이는 것이 REST입니다.

 

2. REST 아키텍처 6가지 제한조건

  1. 인터페이스 일관성 : 일관적인 인터페이스로 분리되어야 한다(가장 중요)
    • 자원은 유일하게 식별 가능해야 하고, HTTP Method로 표현을 담아야 하고, 메시지는 스스로를 설명(self-descriptive) 해야 하고, 하이퍼링크를 통해서 애플리케이션의 상태가 전이(HATEOAS)되어야 한다.
  2. 무상태(Stateless): 각 요청 간 클라이언트의 콘텍스트가 서버에 저장되어서는 안 된다
  3. 캐시 처리 가능(Cacheable): WWW에서와 같이 클라이언트는 응답을 캐싱할 수 있어야 한다.
    • 잘 관리되는 캐싱은 클라이언트-서버 간 상호작용을 부분적으로 또는 완전하게 제거하여 scalability와 성능을 향상한다.
  4. 계층화(Layered System): 클라이언트는 보통 대상 서버에 직접 연결되었는지, 또는 중간 서버를 통해 연결되었는지를 알 수 없다. 중간 서버는 로드 밸런싱 기능이나 공유 캐시 기능을 제공함으로써 시스템 규모 확장성을 향상하는 데 유용하다.
  5. Code on demand (optional) - 자바 애플릿이나 자바스크립트의 제공을 통해 서버가 클라이언트가 실행시킬 수 있는 로직을 전송하여 기능을 확장시킬 수 있다.
  6. 클라이언트/서버 구조 : 아키텍처를 단순화시키고 작은 단위로 분리(decouple)함으로써 클라이언트-서버의 각 파트가 독립적으로 개선될 수 있도록 해준다.

3. REST API 구성

GET /123 HTTP/1.1
Host : chibumps.tistory.com

자원(Resource) - HTTP URI

  • 모든 자원에는 고유 식별 ID가 존재하고, 이 자원은 Server에 존재합니다.
  • 자원을 구별하는 ID는 '/123'와 같은 HTTP URI입니다.
  • Client는 URI를 이용해 자원을 지정하고 해당 자원의 상태(정보)에 대한 조작을 Server에 Request 합니다.

행위(Verb) - Method

  • HTTP Protocol의 Method이용
  • GET(Read), POST(Create), PUT(Update), PATCH(Update), DELETE(Delete)
    GET Read : 정보 요청, URI가 가진 정보를 검색하기 위해 서버에 요청한다.
    POST Create : 정보 입력, 클라이언트에서 서버로 전달하려는 정보를 보낸다.
    PUT Update : 정보 업데이트, 주로 내용을 갱신하기 위해 사용한다. (데이터 전체를 바꿀 때)
    PATCH Update : 정보 업데이트, 주로 내용을 갱신하기 위해 사용한다. (데이터 일부만 바꿀 때)
    DELETE Delete : 정보 삭제, (안전성 문제로 대부분 서버에서 비활성화한다.)

표현(Representation of Resource)

  • Client와 Server가 데이터를 주고받는 형태로 JSON, XML, TEXT, RSS 등이 있습니다.

 

4. REST API 설계 가이드

4.1. URL Rules

1. URI는 동사보다는 명사를, 대문자보다는 소문자를 사용하여야 한다.

Bad Example http://chibumps.tistory.com/testing
Good Example  http://chibumps.tistory.com/test

 

2. 마지막에 슬래시 (/)를 포함하지 않는다.

Bad Example http://chibumps.tistory.com/test/  
Good Example  http://chibumps.tistory.com/test

 

3. 언더바 대신 하이폰을 사용한다.

Bad Example http://chibumps.tistory.com/test_blog
Good Example  http://chibumps.tistory.com/test-blog  

 

4. 파일 확장자는 URI에 포함하지 않는다.

Bad Example http://chibumps.tistory.com/photo.png
Good Example  http://chibumps.tistory.com/photo  

 

5. 행위를 포함하지 않는다.

Bad Example http://chibumps.tistory.com/delete-post/1  
Good Example  http://chibumps.tistory.com/post/1 

 

4.2. Set HTTP Headers

4.2.1 Content-Location

POST, PATCH 같은 요청은 대부분 멱등하지 않다. (멱등, 반환되는 응답 리소스의 결과가 항상 동일)

POST /board
{
"content": "chibumps"
}

 

위와 같은 요청을 여러 번 반복하면, /board/1, /board/2,..., /board/n 과 같이 매번 다른 리소스를 반환한다.

그래서 Server는 Response Header에 새로 생성된 리소스를 식별할 수 있는 Content-Location 속성을 이용한다.

HTTP/1.1 200 OK
Content-Location: /board/1

 

HATEOASContent-Location를 대체할 수 있다.

 

4.2.2 Content-Type

application/json을 우선으로 제공한다.

 

4.2.3. Retry-After

비정상적인 방법(DoS, Brute-force attack 등)으로 API 서버에 Request를 하는 경우 429 Too Many Requests 오류 Response와 함께 일정 시간 뒤 Request 할 것을 나타낸다.

HTTP/1.1 429 Too Many Requests
Retry-After: 3600

Case 1. 인증

  • /auth OAuth, JWT 같은 인증 리소스를 Request 하는 작업
  • /login Id, Password를 이용한 로그인 작업

비정상적인 요청(401) 일 때 두 가지 응답 방안

  • n 시간 동안 n 회만 요청 가능
    • 429 응답과 함께 Retry-After:n
  • n 회만 요청 가능
    • 401 응답과 함께 해당 사용자(IP)는 더 이상 인증 관련 API를 사용할 수 없고 다시 요청하려면 특수한 절차가 필요하다고 Response (Retry-After와 관계없음)

Case2. 자원 요청

  • /posts 특정 사용자가 의도적으로 서버 과부하를 목적으로 반복 요청하는 경우 429 Response.

 

4.2.4 Link

목적: 페이징 처리

다음과 같은 github 방식을 따른다. https://docs.github.com/en/rest/guides/traversing-with-pagination

 

Traversing with pagination - GitHub Docs

The GitHub API provides a vast wealth of information for developers to consume. Most of the time, you might even find that you're asking for too much information, and in order to keep our servers happy, the API will automatically paginate the requested ite

docs.github.com

HTTP/1.1 200 OK
Link: <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=2>; rel="next",
  <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=34>; rel="last"
  • rel 목록
Name Description
next The link relation for the immediate next page of results.
last The link relation for the last page of results.
first The link relation for the first page of results.
prev The link relation for the immediate previous page of results.

 

4.3. Use HTTP Methods

4.3.1. POST, GET, PUT, DELETE 4가지 Methods는 반드시 제공한다.

methods POST GET PUT DELETE
/board 게시글 등록 게시글 전체 조회 게시글 등록 or 게시글 수정 or 405 ERROR 게시글 전체 삭제
/board/1 405 ERROR 게시글 ‘1’ 조회 게시글 ‘1’ 수정 게시글 ‘1’ 삭제

*405 ERROR: 허용되지 않는 HTTP Method 사용

  • Collection에 PUT요청은 보통 지원하지 않으므로 405 ERROR로 응답하기도 한다.
    • Collection: /board/1에서 board, 집합
    • Document: /board/1에서 1, 집합에 속한 자원

4.3.2. OPTIONS, HEAD, PATCH를 사용하여 완성도 높은 API를 만든다.

OPTIONS

현재 End-point에서 제공 가능한 API Method를 Response.

OPTIONS /board/1
HTTP/1.1 200 OK
Allow: GET,PUT,DELETE,OPTIONS,HEAD

 

HEAD

요청에 대한 Header 정보만 Response. body가 없다.

HEAD /users
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 120

 

PATCH

PUT 대신 PATCH Method를 사용한다.

자원의 일부를 수정할 때는 PATCH가 목적에 맞는 Method다.

id title content
1 test mooyaho

 

PUT은 일부(title)만 수정할 때도 바뀌지 않는 속성을 보내야 한다.

PUT /board/1
{
	"title":"chibumps",
	"content":"mooyaho"
}
HTTP/1.1 200 OK
{
	"title":"chibumps",
	"content":"mooyaho"
}

 

PATCH를 이용하여 원래의 목적대로 'title'만 변경하는 요청을 보낸다.

PATCh /board/1
{
	"title":"chibumps"
}
HTTP/1.1 200 OK
{
	"title":"chibumps",
	"content":"mooyaho"
}

 

4.4. Use HTTP Status

 

4.4.1. 의미에 맞는 HTTP status를 리턴한다.

 

Bad Example

HTTP/1.1 200 OK
{
	"result" : false,
	"status" : 400
}
  • status code는 성공을 나타내는 200인데 body에 들어있는 결과는 실패인 400을 나타내고 있다.
    • body 내용으로 성공 or 실패 여부를 판단하는 안 좋은 예
HTTP/1.1 400 Bad Request
{
	"msg" : "ERROR: check parameters."
}

 

4.4.2. HTTP status만으로 상태 에러를 나타낸다.

세부 에러 사항은 Response 객체에 표시하거나, 해당 에러를 확인할 수 있는 link를 표시한다.

 

HTTP status code를 Response에 중복으로 표시할 필요 없다.

 

Bad Example

HTTP/1.1 404 Not Found
{
	"code" : 404,
	"error_code": -765
}

Good Example

HTTP/1.1 404 Not Found
{
	"code" : -765,
	"more_info" : "https://api.test.com/errors/-765"
}

 

4.5. Use the correct HTTP status code

 

4.5.1. 성공 응답은 2XX로 응답한다.

  • 200 : [OK]
  • 201 : [Created]
    • 200과 달리 요청에 성공하고 새로운 리소스를 만든 경우에 응답한다.(POST, PUT에 사용)
  • 202 : [Accepted]
    • Client의 Request를 받은 후, Request는 유효하지만 Server가 아직 처리하지 않은 경우에 응답한다.
    • 비동기 작업에 해당한다.
      • Request에 대한 Response가 일정 시간 후 완료되는 작업의 경우
      • 작업 완료 후 Client에 알릴 수 있는 Server push 작업을 하거나, Client가 해당 작업의 진행 상황을 조회할 수 있는 URL을 응답해야 한다.
      • HTTP/1.1 202 Accepted
        {
        	"links": [
        		{
        			"rel": "self",
        			"method": "GET",
        			"href": "https://api.test.com/v1/users/3"
        		}
        	]
        }
  • 204 : [No Content]
    • Response body가 필요 없는 자원 삭제 요청(DELETE) 같은 경우 응답한다.
    • 200 응답 후 body에 null, {}, [], false로 응답하는 것과 다르다.
      • 204의 경우 HTTP body가 아예 없는 경우이다.

 

4.5.2. 실패 응답은 4XX로 응답한다.

  • 400 : [Bad Request]
    • Client Request가 미리 정의된 parameter 요구사항을 위반한 경우에 응답한다.
    • Parameter의 위치(path, query, body), 사용자 입력 값, 에러 이유 등을 반드시 함께 알린다.
      • Case 1
        {
        	"message" : "'code'(body) must be Number, input 'code': test123"
        }​
      • Case 2
        {
        	"errors": [
        		{
        			"location": "body",
        			"param": "code",
        			"value": "test123",
        			"msg": "must be Number"
        		}
        	]
        }​
  • 401 : [Unauthorized]
  • 403 : [Forbidden]
    • Request는 유효하나 Server 작업 중 접근이 허용되지 않은 자원을 조회하려는 경우
  • 404 : [Not Found]
  • 405 : [Method Not Allowed]
    • 405 code는 404 code와 혼동될 수 있기 때문에 룰을 잘 정하고 시작한다.
    • POST /board/1의 경우 404로 Respons 한다고 생각할 수 있지만, 경우에 따라 405로 응답할 수 있다.
      /board/:bno URL은 GET, PATCH, DELETE Method만 허용되고 POST는 불가한 URL이다.
      • 만약 bno가 1인 게시글이 없는 경우엔 404로 응답하지만(GET, PATCH, DELETE의 경우),
        POST /board/1/board/:bno URL이 POST Method를 제공하지 않기 때문에 405로 응답하는 게 옳다.
    • Allow: GET, PATCH, DELETE HTTP header에 허용 가능한 Method를 표시한다.
  • 409 : [Conflict]
    • Request의 처리가 비즈니스 로직상 불가능하거나 모순이 생긴 경우
    • 예를 들어, DELETE /board/1의 경우, 비즈니스 로직상 게시글에 달린 모든 댓글을 비워야만 게시글을 삭제할 수 있는 규칙이 있을 때 409로 응답한다.
      409 Conflict
      {
      	"message" : "first, delete connected resources."
      	"links": [
      		{
      			"rel": "comments.delete",
      			"method": "DELETE",
      			"href": "https://test.co.kr/board/1/comments"
      		},
      	]
      }​
  • 429 : [Too Many Requests]
    • Retry-After: 3600(HTTP Headers)
    • DoS, Brute-force attack과 같은 비정상적인 접근을 막기 위해 Request의 수를 제한한다.

 

4.5.3. 5XX ERROR는 절대 사용자에게 나타내지 말기!

API Server level에선 500 Error가 나선 안된다.----> 서비스 장애에 해당

API Server는 발생 가능한 모든 Error를 핸들링해야 한다.

만약 API Server를 서빙하는 Web Server(apache, nginx)가 오류일 때는 500으로 응답한다.

 

4.6. Use HATEOAS

REST API는 요청-응답이라는 간단한 구조로 이루어져 있다. 
또한 응답의 내용도 단순하다.

요청이 다음과 같다면,

POST /board
{
	"title":"chibumps",
	"content":"mooyaho"
}

 

Server는 다음과 같이 응답한다.

HTTP/1.1 201 Created
{
	"bno":1,
	"title":"chimbumps",
	"content":"mooyaho"
}

 

여기서 문제는 이 응답만으론 사용자 리스소의 상태가 전이되기엔 정보가 부족하다는 것이다.

REST API가 아닌 HTML 환경에선 눈에 보이는 화면이 있기 때문에 POST /board후에 게시글의 상태가 전이될 수 있는 link를 화면에서 제공할 수 있다.

이 문제를 해결하기 위해 응답 객체에 해당 리소스의 상태가 전이될 수 있는 link들을 함께 제공한다. link들을 통해 리소스의 다음 상태 전이 정보를 동적으로 제공한다.

 

4.6.1. 구성 요소

  • 변경될 리소스의 상태 관계 rel
    • self: 현재 URL 자신, 예약어처럼 쓰인다.
  • 요청 URL href
  • 요청 Method method
  • etc
    {
    	"rel": "self",
    	"href": "http://test.co.kr/board/1",
    	"method": "GET"
    }​

4.6.2. 응답 예제

201 Created
{
	"bno": 1,
	"title": "chibumps",
    "content": "mooyaho",
	"createdAt": "2022-01-24 14:50:00",
	"links": [
		{
			"rel": "self",
			"href": "http://test.co.kr/board/1",
			"method": "GET"
		},
		{
			"rel": "delete",
			"href": "http://test.co.kr/board/1",
			"method": "DELETE"
		},
		{
			"rel": "update",
			"href": "http://test.co.kr/board/1",
			"method": "PATCH",
			"more_info": "http://test.co.kr/docs/board-update"
			"body": {
				"name": "{The value to be modified}"
			}
		},
		{
			"rel": "board.comments",
			"href": "http://test.co.kr/board/1/comments",
			"method": "GET"
		}
	]
}
  • rel의 값은 self를 제외하고 내부 규칙을 정해서 따른다. 의미만 정확히 나오면 된다.
  • more_info, body와 같이 내부 정의된 key를 사용해도 된다.
    • more_info: 해당 link의 세부 정보를 알고 싶은 경우 탐색할 URL
    • body: 해당 link가 POST, PUT인 경우 parameter를 body에 넣어 보내기 때문에 보낼 수 있는 body parameter sample을 안내한다. Parameter가 너무 많거나 제약사항이 엄격한 경우 more_info로 해당 link의 상세 정보를 확인할 수 있게 한다.

5. REST의 장단점

장점 

  • HTTP 프로토콜의 인프라를 그대로 사용하므로 REST API 사용을 위한 별도의 인프라를 구출할 필요가 없다.
  • HTTP 프로토콜의 표준을 최대한 활용하여 여러 추가적인 장점을 함께 가져갈 수 있게 해 준다.
  • HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다.
  • Hypermedia API의 기본을 충실히 지키면서 범용성을 보장한다.
  • REST API 메시지가 의도하는 바를 명확하게 나타내므로 의도하는 바를 쉽게 파악할 수 있다.
  • 여러 가지 서비스 디자인에서 생길 수 있는 문제를 최소화한다.
  • 서버와 클라이언트의 역할을 명확하게 분리한다.

 

단점 

  • 표준이 자체가 존재하지 않아 정의가 필요하다.
  • 사용할 수 있는 메서드가 5가지밖에 없다.
  • HTTP Method 형태가 제한적이다.
  • Browser를 통해 test 할 일이 많은 서비스라면 쉽게 고칠 수 있는 URI보다 Header 정보의 값을 처리해야 하므로 전문성이 요구된다.
  • 구형 브라우저에서 호환이 되지 않아 지원해주지 못하는 동작이 많다.(익스 폴로어)

참조

 

REST - 위키백과, 우리 모두의 백과사전

대한민국의 힙합 음악가에 대해서는 R-EST 문서를 참고하십시오. REST(Representational State Transfer)는 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식이다. 이

ko.wikipedia.org

 

REST란? REST API 와 RESTful API의 차이점?

참고 REST(REpresentational State Transfer)란? REST의 정의 "REpresentational State Transfer" 의 약자로, 자원을 이름(자원의 표현)으로 구분해 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미합니다. 즉..

dev-coco.tistory.com

 

[네트워크] REST API란? REST, RESTful이란?

REST API란 REST를 기반으로 만들어진 API를 의미합니다. REST API를 알기 위해 REST부터 알아보도록 하겠습니다. REST란? REST(Representational State Transfer)의 약자로 자원을 이름으로 구분하여 해당 자원..

khj93.tistory.com

 

'Web' 카테고리의 다른 글

CSS: 박스(box) 모델  (0) 2022.06.16
HTTP Status Code(응답코드)  (0) 2022.01.23
HTTP Cookie(쿠키) & HTTP Session(세션)  (0) 2022.01.23

댓글