RESTful API 설계하기
RESTful API 수준
2008년에 Leonard Richardson은 Web API에 대한 다음과 같은 성숙도 모델을 제안했습니다.
- 수준 0: 한 URI를 정의합니다. 모든 작업은 이 URI에 대한 POST 요청입니다.
- 수준 1: 개별 리소스에 대한 별도의 URI를 만듭니다.
- 수준 2: HTTP 메서드를 사용하여 리소스에 대한 작업을 정의합니다.
- 수준 3: 하이퍼미디어(HATEOAS, 아래에 설명)를 사용합니다.
수준 3은 Fielding의 정의에 따르면 진정한 RESTful API에 해당합니다.
REST API
REST API는 URI만 보고도 직관적으로 이해할 수 있어야합니다.
URI 규칙
/ {①단수:서비스명} / {②버젼} / {③복수:리소스명} / {④아이디} / {⑤복수:리소스명} / {⑥아이디}
ex) /thanks/v1/boards/10/comments/2
- URI의 리소스 depth는 최대 2 depth를 넘기지 않습니다. (가독성이 떨어짐.)
- /thanks/v1/boards/10/comments/2/like/10 ( X )
- /thanks/v1/boards/10/comments/2 ( O )
- URI는 소문자로 작성합니다. 구분이 필요한경우 하이푼으로 구분합니다.
- /thanks/v1/boardReceive ( X )
- /thanks/v1/board-receive ( O )
- 리소스명은 복수명으로 작성합니다.
- /thanks/v1/board ( X )
- /thanks/v1/boards ( O )
- 리소스명은 명사를 사용 합니다. (리소스 행위에 대해서는 HTTP method로 표현합니다)
- /thanks/v1/board-save ( X )
- /thanks/v1/board ( O )
- 버전은 v1,v2,v3로 작성합니다.
- /thanks/v1
- /thanks/v2
- /thanks/v3
HTTP Method
URI의 리소스에 대한 행위 표현은 HTTP Method를 사용합니다.
PATCH는 브라우저마다 사용하지 않는 브라우저가 있어 사용을 지양합니다.
HTTP Method |
description | example |
GET | 리소스 가져오기 | /thanks/v1/boards : 게시글 리스트를 가져옵니다. /thanks/v1/boards/1 : 게시글 1번 글을 가져옵니다. /thanks/v1/boards/1/comments/2 : 게시글 1번 글에 2번댓글을 가져옵니다. |
POST | 리소스 생성 생성 후에는 ID 값을 내려줍니다. |
/thanks/v1/boards : 게시글을 생성합니다. /thanks/v1/boards/1/comments: 게시글 1번 글에 댓글을 생성합니다. |
PUT | 리소스 수정 (리소스가 없는경우 생성합니다) 생성 후에는 ID 값을 내려줍니다. |
/thanks/v1/boards/1 : 1번 게시글을 수정합니다. (없는경우 생성합니다.) /thanks/v1/boards/1/comments/2: 1번 게시글에 2번 댓글을 수정합니다.(없는경우 생성합니다.) |
DELETE | 리소스 삭제 | /thanks/v1/boards/1 : 1번 게시글을 삭제합니다. /thanks/v1/boards/1/comments/2: 1번 게시글에 2번 댓글을 삭제합니다. |
검색
GET방식으로 리소스를 가져올 시 검색은 Query String을 통해서 검색합니다.
1안)
아래와 같이 요청하는 경우 페이징 처리에 정의된 page, size가 검색 조건인지 아니면 페이징 조건인지 구분하기 어렵다.
/thanks/v1/emp?empNm=xxxx
구분을 명확히하기 위해 아래와 같이 요청을 지향합니다.
/thanks/v1/emp?query=empNm=xxx,orgNm=xxxx팀,title=제목입니다.&page=5&size=10
파란색 부분은 URLEncode 해서 전달합니다.
전역 검색
예를들어, board, comment, like 라는 리소스가 있을때 구분없이 모든 리소스에 검색 시 /search의 URI를 사용합니다.
/thanks/v1/search?query=empNm=xxx,orgNm=xxxx팀,title=제목입니다.
특정 리소스에서 검색
예를들어, board 리소스에서만 검색할때는 아래와 같이 사용됩니다.
/thanks/v1/board?query=empNm=xxx,orgNm=xxxx팀,title=제목입니다.
2안)
/thanks/v1/board?query=제목입니다.&searchType=TITLE_AND_CONTENTS&page=5&size=10
- query에 검색할 질의내용을 입력.
- searchType에 제목만 검색할지, 제목 + 내용 검색 할지, 검색타입을 코드값으로 입력.
=> 검색 조건이 여러 필터나 타입으로 검색을 하여 복잡한경우 1안) 사용.
=> 간단한 검색인 경우 2안) 사용.
페이징
https://datajoy.tistory.com/232
에러메시지
HTTP status |
의미 | 필수 | 상태알림목적 | 클라이언트 예외처리가이드 |
200 | OK | O | 성공처리 하였으니 다음 처리 실행 | 다음 진행 |
400 | Bad Request | O | 요청 자체가 잘못 되었으니 확인필요 | 실패처리 |
500 | Internal Server Error | O | 서버쪽 오류이기 때문에 클라이언트는 문제 없음 | 실패처리 |
502 | Bad Gateway | 서버쪽에 트래픽이 몰려 잠깐 오류가 발생하였음 | 1회 재시도 필요 | |
201 | Created | 요청은 잘 받았으니 처리는 걱정할 필요없음 | 무시하고 다음 진행 | |
304 | Not Modified | 요청한 내용과 차이가 없으니 기존 응답을 사용해도 무방함 | 기존 캐싱된 내용 재사용 | |
404 | Not Found | O | 잘못된 주소의 호출로 클라이언트 확인필요. | 실패처리 |
401 | Unauthorized | 로그인 후에 사용이 가능함. 권한 확인이 가능한 토큰이 없거나 유효하지 않음 | 실패처리 후 로그인 재시도 필요 | |
403 | Forbidden | 가지고 있는 권한으로는 사용할 수 없는 기능임 | 실패처리 |