일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Git
- 스프링
- Vue
- aws
- oracle
- 프로그래머스
- IntelliJ
- error
- 에러
- Spring
- 방법
- GitHub
- 오라클
- 코틀린
- 생성
- Eclipse
- jquery
- 알고리즘
- kotlin
- JavaScript
- mybatis
- Java
- 시큐리티
- db
- JPA
- 넥사크로
- 자바
- Security
- 쿼리
- 함수
- Today
- Total
송민준의 개발노트
RESTfull API 설계 고려사항들... 본문
● Rest란?
Representational State Transfer이라는 용어의 약자이다.
로이 필딩이란 사람에게서 나온 개념이다.
● Rest의 구성은?
1. 자원(RESOURCE) - URI
2. 행위 - HTTP METHOD
3. 표현(Representations)
● Rest의 특징은?
1. Uniform interface
- URI로 지정한 리소스에 대한 조작을 통일되고 한정적 인터페이스로 수행하는 아키텍처임
2. Stateless
- 상태가 없는 특징을 가진다. 즉 상태정보를 따로 저장하고 관리하지 않는다.
3. Cacheable(캐시 가능)
- HTTP가 가진 캐시 기능을 적용 가능함
4. Self-Descriptiveness
- 자체 표현 구조를 통해 쉽게 이해할 수 있다.
5. Client-Server
- 각각 구분이 명확해서 서로간 의존성이 줄어들고 개발내용이 명확해짐
6. 계층형
- 다중 계층으로 구성 가능, 보안, LB, 암호화 등 계층을 추가해 구조상 유연상을 둘 수 있음
● URL Rules
1. 마지막에 ' / ' 를 포함하지 않는다.
//Bad
http://test.com/test/
//Good
http://test.com/test
2. _ 대신 - 를 사용한다.
//Bad
http://test.com/test/case_one
//Good
http://test.com/test/case-one
3. 소문자를 사용한다.
//Bad
http://test.com/test/caseOne
//Good
http://test.com/test/case-one
4. 동사(행위)는 URL에 포함하지 않는다.
//Bad
POST : http://test.com/test/1/delete-case/1
//Good
DELETE http://test.com/test/1/case/1
5. 컨트롤 자원을 의미하는 URL 예외적으로 동사를 허용한다.
//Bad
http://test.com/test/duplicating
//Good
http://test.com/test/duplicate
6. 컬렉션, 스토어 이름으로 복수 명사를 사용해야 한다.
//Bad
http://test.com/test/1
//Good
http://test.com/tests/1
7. URI에 행위에 대한 동사 표현이 들어가면 안된다.
//Bad
Delete http://test.com/test/delete/1
//Good
Delete http://test.com/test/1
8. 확장자가 들어가지 않는다.(ex. jpg) - URI 는 고유한 리소스를 나타내야함
//Bad
Delete http://test.com/test/dog.jpg
//Good
Delete http://test.com/test/dog
● HTTP Headers
1.Content-Location
- POST 요청의 대부분은 반환되는 응답 리소스의 결과가 항상 동일하지 않는다.
POST /users
{
"name": "hak"
}
위와 같은 요청은 매번 다른 리소스를 반환함.
/users/1
/users/2
/users/3
...
따라서 응답 헤더에 새로 생성된 리소스를 식별할 수 있는 Content-Location 속성을 이용
HTTP/1.1 200 OK
Content-Location: /users/1
- 반면 GET, PUT 등의 요청은 반환되는 응답 리소스가 동일하다.
- HATEOAS로 Content-Location을 대체할 수 있다.
2. Content-Type
- application/json을 우선으로 제공함.
- 응답 포맷을 여러개로 나누지 말자(ex. xml 같은...)
3. Retry-After
- 비정상적인 방법(디도스 공격 등)으로 API 서버를 이용하려는 경우 429 Too Many Requests 오류 응답과 함께 일정 시간 뒤 요청할 것을 나타냄
HTTP/1.1 429 Too Many Requests
Retry-After: 3600
1) 인증
/auth OAuth, JWT 같은 인증 관련 리소스를 요청하는 작업
/login Id, Password를 이용한 로그인 작업
㉮ 비정상적인 요청(401) 일 때 두 가지 응답 방안
① n 시간 동안 n회만 요청 가능 : 429 응답과 함께 Retry-After b
② n 회만 요청 가능 : 더 이상 인증 관련 API 사용할 수 없다는 응답
2) 자원 요청
/posts 특정 사용자가 의도적으로 서버 과부화를 목적으로 반복 요청하는 경우
- n시간 동안 n회 이상 요청한 경우
4. Link
- 페이징 처리를 위해 사용
developer.github.com/v3/#pagination
● Use HTTP methods
1. GET, POST, PUT, DELETE 4가지는 반드시 제공한다.
methods | POST | GET | PUT | DELETE |
/users | 사용자 추가 | 사용자 전체 조회 | 사용자 추가, 수정 | 사용자 전체 삭제 |
/users/1 | 405 ERROR | 1번 사용자 조회 | 1번 사용자 수정 | 사용자 1번 삭제 |
2. OPTIONS, HEAD, PATCH를 사용하여 완성도 높은 API를 만든다.
1) OPTION : 현재 ENDPOINT가 제공 가능한 API method를 응답함.
OPTIONS /users/1
------------------------
HTTP/1.1 200 OK
Allow: GET,PUT,DELETE,OPTIONS,HEAD
developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
2) HEAD : 요청에 대한 Header 정보만 응답한다. BODY가 없음
HEAD /users
--------------------
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 120
developer.mozilla.org/ko/docs/Web/HTTP/Methods/HEAD
3) PATCH : PUT대신 PATCH method를 사용한다. 자원의 일부를 수정할 때는 PATCH가 목적에 맞는 method 다.
- 일반적으로 PUT 요청 시 일부분만 보낼 경우 나머지는 default로 되는게 원칙이지만 대부분 이렇게 개발하진 않는다.
// PUT 일부만 보낼 경우
PUT /user/1
{
"level":11
}
-------------------------
HTTP/1.1 200 OK
{
"name": null,
"level": 11
}
// PUT 수정안하는 값까지 보냄
PUT /users/1
{
"name": "1",
"level": 11
}
----------------------------
HTTP/1.1 200 OK
{
"name": "1",
"level": 11
}
이상적인 방법
PATCH /users/1
{
"level":11
}
----------------
HTTP/1.1 200 OK
{
"name": "1",
"level": 11
}
● Use HTTP status
1. 의미에 맞는 HTTP status를 리턴한다.
// Bad
HTTP/1.1 200 OK
{
"result" : false
"status" : 400
}
// Good
HTTP/1.1 400 Bad Request
{
"msg" : "check your parameter"
}
2. HTTP status만으로 상태 에러를 나타낸다.
//Bad
HTTP/1.1 404 Not Found
{
"code" : 404,
"error_code" : -765
}
//Good
HTTP/1.1 404 Not Found
{
"code" : -765,
"more_info" : "https://test.com/users/-765
}
● 정확한 HTTP status code 사용
1. 성공 응답은 2XX로 응답
200 : OK
201 : Created 요청에 성공 및 새로운 리소스를 만든 경우에 응답
202 : Accepted 요청 받은 후 요청은 유효하나 서버가 아직 처리하지 않은 경우 응답(비동기)
작업 완료 후 클라이언트에 push 작업을 하거나 클라이언트가 해당 작업의 상황을 알 수 있는
조회 URL를 응답해야한다.
ex)
HTTP/1.1 202 Accepted
{
"links": [
{
"rel": "self",
"method": "GET",
"href": "반환주소"
}
]
}
204 : No Content 응답 body가 필요없는 자원 삭제 요청에 응답(DELETE)
200 응답에 body가 null, {}, [], false 로 응답하는 것과는 다름
204는 아예 없음
2 실패 응답은 4XX로 응답한다.
400 : [Bad Request] 클라이언트 요청이 미리 정의된 파라미터 요구사항을 위반한 경우
사용자 입력 값, 에러 이유 등을 반드시 알린다.
ex1)
{
"message" : "'name'(body) must be Number, input 'name': text123"
}
ex2)
{
"error": [
{
"location":"body",
"param":"name",
"value":"test123",
"msg":"must be Number"
}
]
}
401 : [Unauthorized]
403 : [Forbidden] 해당 요청은 유효하나 서버 작업 중 접근이 허용되지 않은 자원 조회함
404 : Not Found
405 : [Method Not Allowed]
ex) 405와 404를 구분을 잘해야 한다.
POST /users/1의 경우 404로 응답한다고 생각할 수 있지만 경우에 따라 405로 응답.
/users/:id URL은 GET,PATCH,DELETE method는 허용되지만 POST는 불가함.
3. 5XX 에러는 사용자에게 나타내지 않는다.
● HATEOAS 사용
- REST API는 요청-응답 이라는 간단한 구조로 이루어져 있다. 여기서 문제는 간단한 응답만으론 사용자 리소스의 상태가 전이되기엔 정보가 부족하다는 것이다. 이 문제를 해결하기 위해 응답 객체에 해당 리소스의 상태가 전이될 수 있는 link들을 함께 제공한다. link들을 통해 리소스의 다음 상태 전이 정보를 동적으로 제공한다.
1. 구성 요소
- 변경될 리소스의 상태 관계 rel - self : 현재 URL 자신
- 요청 URL href
- 요청 Method method
{
"rel": "self",
"href": "http://test.com/users/1",
"method": "GET"
}
2. 응답 예제
201 Created
{
"id": 1,
"name": "hak",
"createdAt": "2018-07-04 14:00:00"
"links": [
{
"rel": "self",
"href": "http://api.test.com/users/1",
"method": "GET"
},
{
"rel": "delete",
"href": "http://api.test.com/users/1",
"method": "DELETE"
},
{
"rel": "update",
"href": "http://api.test.com/users/1",
"method": "PATCH",
"more_info": "http://api.test.com/docs/user-update"
"body": {
"name": "{The value to be modified}"
}
},
{
"rel": "user.posts",
"href": "http://api.test.com/users/1/posts",
"method": "GET"
}
]
}
참고 블로그 및 문헌
'네트워크' 카테고리의 다른 글
윈도우 포트 킬(window port kill) (0) | 2020.07.03 |
---|---|
HTTP/1.1 쿠키 헤더 필드 (0) | 2020.01.10 |
HTTP/1.1 엔티티 헤더 필드 (0) | 2019.12.30 |
HTTP/1.1 리스폰스 헤더 필드 (0) | 2019.12.23 |
HTTP/1.1 리퀘스트 헤더 필드 (0) | 2019.12.15 |