RESTful 에 대한 이해 - 2
다양한 web service에서 제공하는 RESTful api
들에 왜 RESTful
이 붙는지, 그리고 그것이 어떤 것을 의미하는 것인지를 공부하고 정리하기 위해 이 포스트를 작성합니다.
개요
하나의 web api
는 베포되고 나면 수정이 어렵다. 특히 클라이언트가 있는 상태라면 더더욱 그러하다.(이를 해결하기 위해 버전을 주고 URI를 분리하기도 한다) 그렇기 때문에 디자인을 신중하게 해야하는데 별도의 가이드가 없는 상황에서는 다른 선구자(?)들의 방식들을 참고할 수밖에 없다. 시간이 된다면 다른 RESTful web api
를 분석하도록 하겠다. 안될거야 아마
이 포스트에서는 권장되는 방식들 중 내 입맛에 맞아 보이는 것들을 모아서 정리하려 한다.
권장 REST 디자인
Resource
URI는 간단하고 직관적이여야 한다.
REST API
의 URI는 그 자체만으로 직관적으로 이해가 가야 한다.
# 이 resource가 task들의 집합과 관련이 있구나.. 이 api가 version 2인가보다..
/v2/tasks
# tasks들의 집합중에 id 2를 가지고 있는 resource와 관련이 있는가보당..
/v2/tasks/2
동사보다는 명사를 사용하자
URI에 resource를 다루는 행동을 포함하지 않도록 한다. 이러한 부분들이 필요할 경우에는 method를 통해 정의하는 것이 좋다.
아래 URI들은 안티패턴이다.
GET /getTasks
POST /deleteTask/2
아래와 같이 CRUD를 이용해서 구현하는 것을 권장한다.
GET /tasks # task 리스트 return
PUT /tasks/2 # id가 2인 task 수정
POST /tasks # task 생성
DELETE /tasks/2 # 2번 task 삭제
일반적으로 Collection을 나타내는 URI
에 권장되는 method 동작은 아래와 같다.
Resource | POST | GET | PUT | DELETE |
---|---|---|---|---|
/tasks | 새로운 task 추가 | task들의 목록 리턴 | 다수의 task 목록을 업데이트 | 모든 task 삭제 |
/tasks/2 | 동작하지 않음 | ID가 2인 task 정보 리턴 | ID가 2인 task 정보 업데이트 | ID가 2인 task 정보 삭제 |
하지만 특정 경우에는 위의 CRUD에 매칭이 되지 않을 경우가 있다.
GET /v2/timers/2 # 이는 2번 timer에 대한 정보를 받아온다.
# 이 타이머를 시작하고 싶었을 때는 어떤 method를 사용해야 할까?
# POST /v2/timers/2 로 표현하자니,, 멈추는 행위와 재시작하는 행위도 표현해야 한다는 문제가 있다.
위와 같은 경우에는 POST
를 사용해서 아래와 같은 URI를 사용하는 것을 권장한다.
- /v2/timers/2/start
- /v2/timers/2/stop
- /v2/timers/2/restart
URI에 CRUD와 관련된 내용만큼은 포함하지 않는 것이 좋다. flickr의 api가 이러한 부분들을 포함하고 있다.
단수보다는 복수 명사 사용
Collection에 대해서는 복수 명사를 사용한다.
/v2/task -> /v2/tasks
소문자를 사용한다.
URI에서 대문자와 소문자는 다른 리소스를 나타낸다. 대문자가 들어가야 할 분명한 이유가 있는 경우가 없다면 가급적이면 소문자로 작성하여 혼란을 피하는 것이 좋다.
/v2/tasks != /v2/TASKS != /v2/Tasks
구분자로 hyphen을 사용
REST에서 URI는 그 자체로도 의미를 갖기 때문에 공백이 들어갈 경우 %20
이 들어가 가독성이 떨어질 수 있다. 그렇기 때문에 hyphen(-)으로 공백을 대체하는 것이 좋다. underscore는 web에서 아주 흔한 링크 및줄로 인해 가려질 수 있어 권장되지 않는다.
soring
sort parameter를 사용한다.
pagination
filter
pretty print 기능
기본적으로는 공백을 없애지만 ?pretty=true
로 제공하면 좋다.
작성중..
요청 Method 별 역할
- GET Method나 POST Method를 사용하여 다른 요청 Method를 처리해서는 안된다.
- GET Method는 리소스의 상태 표현을 얻는 데 사용해야 한다.
- 응답 헤더를 가져올 때는 HEAD Method를 사용해야 한다.
- PUT Method는 리소스를 삽입하거나 저장된 리소스를 갱신하는 데 사용해야 한다.
- PUT Method는 변경 가능한 리소스를 갱신하는 데 사용해야 한다.
- POST Method는 Collection에 새로운 리소스를 만드는 데 사용해야 한다.
- POST Method는 Controller를 실행하는 데 사용해야 한다.
- DELETE Method는 그 부모에서 리소스를 삭제하는 데 사용해야 한다.
- OPTIONS Method는 리소스의 사용 가능한 인터렉션을 기술한 메타데이터를 가져오는 데 사용해야 한다.
- e.g.,
Allow: GET, PUT, DELETE
- e.g.,
응답 상태 코드
개략적인 코드
코드 | 설 명 |
---|---|
1xx: 정보 | 전송 프로토콜 수준의 정보 교환 |
2xx: 성공 | 클라이언트 요청이 성공적으로 수행됨 |
3xx: 재전송 | 클라이언트는 요청을 완료하기 위해 추가적인 행동을 취해야 함 |
4xx: 클라이언트 오류 | 클라이언트의 잘못된 요청 |
5xx: 서버 오류 | 서버쪽 오류로 인한 상태코드 |
규칙
200 OK
는 일반적인 요청 성공을 나타내는 데 사용해야 한다.200 OK
는 응답 바디에 에러를 전송하는 데 사용해서는 안된다- REST API는 부실한 HTTP 클라이언트에 부합하려는 타협을 해서는 안된다
201 Created
는 성공적으로 리소스를 생성했을 때 사용해야 한다.202 Accepted
는 비동기 처리가 성공적으로 시작되었음을 알릴 때 사용해야 한다.204 No Content
는 응답 바디에 의도적으로 아무것도 포함하지 않을 때 사용한다.301 Moved Permanently
는 리소스를 이동시켰을 때 사용한다.- URI에 상당부분 수정되었을 경우에 사용되며, 새로운 URI를 Location으로 제공해야 한다.
302 Found
는 사용하지 않는다.- 명확하지 않아 혼란이 생길 수 있어
303 See Other
나307 Temporary Redirect
를 사용한다(물론 적합할 경우에)
- 명확하지 않아 혼란이 생길 수 있어
303 See Other
는 다른 URI를 참조하라고 알려줄 때 사용한다.304 Not Modified
는 대역폭을 절약할 때 사용한다.- cookie
307 Temporary Redirect
는 클라이언트가 다른 URI로 요청을 다시 보내게 할 때 사용해야 한다.- 일종의 Redirection
400 Bad Request
는 일반적인 요청 실패에 사용해야 한다.- 4xx중 적절한게 없을 경우 사용
401 Unauthorized
는 클라이언트 인증에 문제가 있을 때 사용해야 한다.403 Forbidden
은 인증 상태에 상관없이 엑세스를 금지할 때 사용해야 한다.404 Not Found
는 요청 URI에 해당하는 리소스가 없을 때 사용해야 한다.405 Method Not Allowed
는 HTTP Method가 지원되지 않을 때 사용해야 한다.406 Not Acceptable
은 요청된 리소스 미디어 타입을 제공하지 못할 때 사용해야 한다.- Accept요청 해더에 있는 미디어 타입들을 만족시킬 수 없는 경우
409 Conflict
는 리소스 상태에 위반되는 행위를 했을 때 사용해야 한다.- 요청이 충돌이 나는 경우
412 Precondition Failed
는 조건부 연산을 지원할 때 사용한다.- 조건부 연산이 존재할 경우 그를 충족시키지 못할때
415 Unsupported Media Type
은 요청의 페이로드에 있는 미디어 타입이 처리되지 못했을 때 사용해야 한다.- json만 지원하는 URI에 xml을 요청 할때
500 Internal Server Error
는 API가 잘못 작동할 때 사용해야 한다.- 일반적인 REST API의 오류 응답
- 대부분의 웹 프레임워크는 exception이 발생할 경우 이를 발생시킨다.
reference
-
[Best Practices for Designing a Pragmatic RESTful API Vinay Sahni](http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api) - 조대협의 블로그 :: REST 연재-1회 REST 아키텍쳐의 기본
-
[Spoqa Tech Blog REST 아키텍처를 훌륭하게 적용하기 위한 몇 가지 디자인 팁](https://spoqa.github.io/2012/02/27/rest-introduction.html) -
[GitHub API v3 GitHub Developer Guide](https://developer.github.com/v3/)