HTTP
[API] 1. RESTful API란?
foxlee
2020. 11. 1. 10:09
참고 링크
1. 깃헙 http-api-design
2. stackoverflow /login or /register -> /session
3. stackoverflow return status for empty data of users/9
4. Naming
다음 글 - 2021.11.01 - [개발 고민들] - [API] 2. RESTFUL API - RESPONSE STATUS CODE 적용하기
HTTP
- 무상태 프로토콜
- 장점 : 단순함과 확장성이 높음(서버가 클라이언트상태 보전하지 않아 전송간에 서로 연관이 없어 확장성이 높음)
- 단점 : 클라이언트에서 추가 데이터 전송 필요(데이터 전송마다 그전 전송에 대한 정보가 없음)
- 실무에서는 무상태는 로그인이 필요없는 단순한페이지
- 상태유지의 예로는 로그인으로 로그인 했다는 상태를 서버에서 유지(쿠기, 서버 세션 등으로)
- 비연결성
- 연결을 유지하지 않기 때문에 요청 수가 많아도 빠른 속도 응답이 가능하고 서버 자원을 효율적으로 사용 가능
- 단점으로는 3 Way Handshake 으로 매번 연결을 새로 맺어야 해서 시간이 늘어남
- 위의 단점을 개선하기 위해서 지속 연결을 통해 연결을 잠시 유지하는 방법이 있음
메서드 종류
- GET: 리소스 조회
- 데이터 조회로 주로 쿼리 파라미터를 통해 필터등의 조건 등을 추가하여 조회
- 메세지 바디를 사용해 전달은 가능하지만 지원하지 않는 곳이 많아서 안 쓰는 게 나음
- POST: 리소스 생성 또는 다른 곳에 해당하지 않는 데이터 처리
- 메세지 바디를 통해 서버로 데이터 전달
- 보통 리소스가 생성되면 생성된 위치를 응답으로 보내줌 -> 헤더에 Location: /members/2
- 생성(유저)뿐만 아니라 각종 비지니스 로직, 정책을 통한 로직 등에 사용
- 다른 메서드를 사용하기 애매한 경우
- PUT: 리소스 전체 대체, 없으면 생성
- 클라이언트에서 리소스의 위치(userID 등)를 알고 있음
- 그동안 아래의 PATCH를 PUT으로 사용했었음..(물론, 절대적인 건 없음, 상황에 맞게, 팀워들과 상의 후 결정)
- PATCH: 리소스 일부 변경
- DELETE : 리소스 삭제
- HEAD: GET에서 메세지 바디 없이 상태줄, 헤더만 반환
- 그 외 OPTIONS, CONNECT, TRACE 가 있음
HTTP 메서드의 속성
- 안전
- 아무리 많이 호출해도 같은 요청에는 같은 결과
- 다른 건 신경쓰지 않으며 오로지 리소스가 변경이 되는 것에만 신경 씀(과부화로 인한 에러발생과는 관계 없음)
- 멱등
- 같은 API 호출을 여러번 해도 그 결과는 같다
- GET - 여러번 조회해도 그 결과는 같음
- PUT - 같은 요청을 여러번 해도 그 결과는 같음
- DELETE - 결과를 삭제하고 결과적으로 삭제되므로 같음
- POST - 두번 호출하번 요청이 두번 일어나 중복되는 결과가 생길 수 있음
- 멱등 활용 > 에러/TIMEOUT 등으로 클라이언트가 같은 요청을 다시 해도 되는가?
- 캐시가능
- GET, HEAD 정도는 캐시 가능
URI 설계 개념
- 문서(단일 개념, 객체 인스턴스, 데이터베이스 ROW) - /members/20, /images/logo.png
- 컬렉션(서버에서 관리하는 리소스 디렉터리로 서버가 리소스의 URI를 생성하고 관리)
- 스토어(클라이언트가 리소스의 URI를 알고 관리함 - 파일)
- 컨트롤러, 컨트롤러 URI(위의 개념으로 해결하기 어려운 경우로 동사를 직접사용)
- Naming 참고
적절한 상태 코드 반환
- 200 - GET, DELETE(동기), PATCH(동기)
- 201 - POST(동기)
- 202 - POST, DELETE, PATCH 비동기
- 204 - No content : 삭제 후 반환할 데이터가 없는 경우
- 300 -
- 4xx - (클라이언트 에러)요청파라미터가 잘못된거나 리소스 자체가 없는 경우
- 클라이언트에서 잘못 보냄,
- 클라이언트에서 명세대로 요청하고 있다면 400 에러를 보내주면 안됨
- 비지니스 로직에 대한 실패라면 200으로보내주고 이에 대한 정보를 메세지로 보내줘야함 { "Result": "Failed", "Reason": "Error ~"}
- 401 Unauthorized
- 403 Forbidden
- 404 Not found
- 5xx - 서버 에러
- METHOD는 GET/POST/PUT/DELETE 등으로 어떤 목적을 취하는지 명확하게 보여주고 이와 같은 action이 url 에는 넣지 않는 것이 좋다.(어쩔수 없는 경우 넣거나, restful 한 api가 아닐뿐이지 잘못된건 아니다. 상황에 맞게 개발!)
리소스
- 반환하는 리소스는 가능한 전체 리소스를 반환
- 리소스 아이디 제공
경로 포맷은 일정하게
- 리소스의 이름을 복수형으로,
- 리소스 아이디 제공
Dash(-)사용
- api/app-setups
Nested 데이터
- { "name": "service-production", "owner": { "id": "5d8201b0..." } } (O)
{ "name": "service-production", "owner_id": "5d8201b0..." }{X)
구조화된 에러
- 일정한 에러 메세지
- { "id": "rate_limit", "message": "Account reached its API rate limit.", "url": "관련 url"}
Etags로 캐시 지원
- 모든 응답의 헤더에 Etag 포함시킴, 반환되는 리소스의 특정한 버전을 확인, IF-None-Match 헤더의 값을 제공
로그인/ 로그아웃 엔드포인트
- RESTFUL API에 대해서 모르기 전에는 login, logout 을 엔드포인트에 적용했었는데, 사실상 로그인 로그아웃은 세션이 생성되고 폐기되는 것이다.
- Login -> POST /session (또는 username/session)
- Logout -> DELETE /session (또는 username/session)
데이터가 없는 리소스에 대한 상태 값
- 404 가 적절
- 204 No content
- 데이터가 없기에 상태 코드 값으로는 괜찮으나 HTTP 스펙에 의하면 브라우저는 뷰를 바꾸지 말라는 것으로 이해함
- 요청에 대한 성공을 나타내고 반환할 데이터가 없는 경우에 적절함(DELETE)
- GET users/9 에 대한 응답으로는 적절하지 않음
- GET /users 200 [John, Peter]
- GET /users/john 200 John - /users/[string:name]
- GET /unknown-url-egaer 404 Not Found
- GET /users/kyle 404 User Not found - /users/[string:name] - 바로 리소스에 접근하는 url로 존재하는 데이터가 없으므로,
- GET /users?name=kyle` 200 [] - search 와 같은 기능으로
- DELETE /users/john 204 No Content
리소스에 대한 기준.
- phrsal verb 에서 영어 구동사들을 동사와 부사 또는 전치사가 같이 합쳐진다. 구동사들의 동사를 가져오는 데 처음에는 내가 저장한 구동사들을 리소스로 생각하고 필터 플래그를 주어 only_verb(동사만), only_particle(부사, 전치사만) 등 과 같은 플래그를 통해 동사 리스트, 전치사, 부사 리스트를 반환하도록 했으나 verbs, particle 다른 리소스로 변경예정
phrsalverbs/?only_verb=0&only_particle=0- -> verbs/ particles/ 로 변경