1. HTTP API를 만들어보자
요구사항 및 API URI 설계
요구사항 기반으로 API를 만들게 되면, 위와 같이 현업에서 잘못된 API URI 설계를 한다.
가장 중요한 것은 리소스 식별이다.
API URI 설계 분리
- 리소스 : 회원
- 행위 : 조회, 등록, 수정, 삭제
API URI 설계를 할 때 리소스와 해당 리소스를 대상으로 하는 행위를 분리해야 한다. 회원이라는 리소스만 식별하고 회원 리소스를 URI에 매핑을 하면 된다.
API URI 재설계
API URI 재설계를 했지만 행위는 구분이 되지 않는다. 구분하는 방법은 URI 리소스만 식별해 놓으면 HTTP 메서드인 GET, POST, PUT, DELETE 이런 것들이 조회, 등록, 수정, 삭제 역할을 대신해준다.
* 계층 구조상 상위를 컬렉션으로 보고 복수 단어 사용 권장(member → members)
2. HTTP 메서드 - GET, POST
HTTP 메서드 종류
- GET : 리소스를 조회
- POST : 요청 데이터를 담아서 처리
- PUT : 리소스를 대체, 해당 리소스가 없으면 생성
- PATCH : 리소스 부분 변경
- DELETE : 리소스 삭제
- HEAD : GET과 동일하지만 메시지 부분을 제외하고 상태 줄과 헤더만 반환
- OPTIONS : 대상 리소스에 대한 통신 가능 옵션(메서드)를 설명 (주로 CORS에서 사용)
- TRACE : 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행
GET과 POST는 클라이언트가 서버에 뭔가 요청을 할 때 기대하는 행동이다.
GET
리소스를 조회한다. 서버에 전달하고 싶은 데이터는 쿼리 파라미터 또는 쿼리 스트링을 통해서 전달한다. GET은 메시지 바디를 전달할 수 있지만 실무에서는 바디에 보통 데이터를 넣지 않는다. 지원하지 않는 서버들이 많아서 권장하지 않는다.
클라이언트가 /members/100 GET하고 요청하면 서버에서 GET 메시지가 도착한다. 서버에서는 /members/100 에서 데이터베이스를 조회해서 응답 메시지를 만들어서 클라이언트에게 보낸다.
POST
클라이언트에서 메시지 바디를 통해서 서버로 요청해서 서버가 데이터를 처리하는 모든 기능을 수행한다. 주로 전달된 데이터로 신규 리소스 등록하거나 변경된 프로세스를 바꿀 때 많이 이용한다.
리소스를 /members POST로 전달하면 서버 입장에서는 그 데이터를 내부적으로 어떻게 쓸꺼야라고 미리 서로 약속을 해놓은다. 클라이언트는 필요한 데이터를 전달한다. 그러면 서버에서는 신규로 등록한다고 /members에서 100 신규 리소스 식별자를 생성한다. 신규로 자원이 생산 된 경로를 응답메시지로 보낸다.
POST 예시, 요청 데이터를 어떻게 처리한다는 뜻일까?
- 스펙 : POST 메서드는 대상 리소스가 리소스의 고유 한 의미 체계에 따라 요청에 포함 된 표현을 처리하도록 요청합니다. (구글 번역)
- 예를 들어 POST는 다음과 같은 기능에 사용됩니다.
- HTML 양식에 입력 된 필드와 같은 데이터 블록을 데이터 처리 프로세스에 제공
- ex) HTML FORM에 입력한 정보로 회원 가입, 주문 등에서 사용
- 게시판, 뉴스 그룹, 메일링 리스트, 블로그 또는 유사한 기사 그룹에 메시지 게시
- ex) 게시판 글쓰기, 댓글 달기
- 서버가 아직 식별하지 않은 새 리소스 생성
- ex) 신규 주문 생성
- 기존 자원에 데이터 추가
- ex) 한 문서 끝에 내용 추가하기
- HTML 양식에 입력 된 필드와 같은 데이터 블록을 데이터 처리 프로세스에 제공
- 정리 : 이 리소스 URI에 POST 요청이 오면 요청 데이터를 어떻게 처리할지 리소스마다 따로 정해야 함 → 정해진 것이 없음
POST 정리
1. 새 리소스 생성(등록)
- 서버가 아직 식별하지 않은 새 리소스 생성
2. 요청 데이터 처리
- 단순히 데이터를 생성하거나, 변경하는 것을 넘어서 프로세스를 처리해야 하는 경우
- ex) 주문에서 결제완료 → 배달시작 → 배달완료 처럼 단순히 값 변경을 넘어 프로세스의 상태가 변경되는 경우
- POST의 결과로 새로운 리소스가 생성되지 않을 수도 있음
- ex) POST /orders/{orderId}/start-delivery (컨트롤 URI)
3. 다른 메서드로 처리하기 애매한 경우
- ex) JSON으로 조회 데이터를 넘겨야 하는데, GET 메서드를 사용하기 어려운 경우
- 애매하면 POST
3. HTTP 메서드 - PUT, PATCH, DELETE
PUT
리소스가 있으면 대체하고 리소스가 없으면 생성한다. POST와 다른 점은 PUT은 클라이언트가 구체적인 리소스의 전체 위치를 알고 URI를 지정해서 서버에게 전달한다는 것이다.
PUT - 리소스가 있을 경우
클라이언트가 /members/100 리소스 지정해서 데이터를 서버에게 보내면 서버도 /members/100 리소스가 있다. 그러면 클라이언트가 보낸 리소스로 대체해버린다.
PUT - 리소스가 없을 경우
클라이언트가 members/100 리소스 지정해서 데이터를 서버에게 보냈는데 서버에서 해당 리소스가 없어서 신규 리소스로 생성이 된다.
PUT 주의사항
클라이언트가 /members/100 데이터에 username이 없고 age로 지정해서 보내면 서버에서는 age를 업데이트를 하는데 username 자체가 날아가버린다. 기존 리소스를 새로운 리소스로 완전히 대체한다. 이렇게 되면 리소스를 수정하기 어렵다.
PATCH
리소스를 부분 변경한다. 클라이언트가 /members/100 데이터에 username이 없고 age로 지정해서 보내면 서버에서는 username은 남아있고 age만 변경한거다.
DELETE
리소스를 삭제한다. 클라이언트가 /members/100 를 삭제해달라고 요청하면 서버에서 리소스를 삭제한다.
4. HTTP 메서드의 속성
- 안전(Safe Methods)
- 멱등(Idempotent Methods)
- 캐시가능(Cacheable Methods)
안전(Safe Metods)
호출해도 리소스를 변경하지 않는다.
- GET은 단순히 조회만 하기 때문에 안전하다. 한 번 호출해도 여러 번 호출해도 변경이 일어나지 않아서 안전하다.
- POST, PUT, PATCH, DELETE는 안전하지 않다.
- 만약에 그래도 계속 호출해서 서버에서 로그가 계속 쌓게되서 서버 장애가 일어난다면, 안전은 그런 부분까지 고려하지 않는다. 안전은 해당 리소스만 고려하기 때문이다.
멱등(Idempotent Methods)
f(f(x)) = f(x)
한 번 호출해도 두 번 호출해도 100번 호출해도 결과는 동일하다.
- GET은 한 번 조회하든 두 번 조회하든 같은 결과로 조회된다.
- PUT은 결과를 대체하기 때문에 같은 요청을 여러 번 해도 최종 결과는 동일하다.
- DELETE는 결과를 삭제하기 때문에 같은 요청을 여러 번 해도 삭제된 결과는 동일하다.
- POST는 멱등이 아니다. 두 번 호출하면 같은 결제가 중복해서 발생해서 새로운 리소스로 구별이 된다.
멱등은 외부 요인으로 중간에 리소스가 변경되는 것까지 고려하지 않는다. 똑같은 클라이언트가 동일한 요청했을 때만 멱등한다. 즉 멱등은 동시성 문제까지 고려하지 않는다.
멱등의 활용
자동 복구 매커니즘로 활용할 수 있다. 클라이언트가 자동 DELETE를 호출했는데 서버에서 잘 되고 있는지 안 되고 있는지 응답이 없다. 클라이언트가 다시 자동 DELETE를 재시도 해도 멱등한다. 실무에서 이런 전반적으로 자동 복구 매커니즘을 많이 사용한다.
캐시가능(Cacheable Methods)
웹 브라우저에 용량이 큰 이미지를 한번 요청을 하면 그 다음에 똑같이 용량이 큰 이미지를 요청할 필요없다. 똑같은 이미지를 서버에서 다운로드 받으면 오래 걸린다. 그래서 로컬 PC에 웹 브라우저 저장을 하고 있을 때 캐시라고 한다. 캐시는 GET, HEAD, POST, PATCH 가능 하지만 실제로는 GET, HEAD 정도만 캐시로 사용한다. POST, PATCH는 캐시를 하려면 본문 내용으로 리소스랑 캐시 키가 맞아아야 되는데 복잡해서 구현이 쉽지 않다. GET, HEAD는 URI만 캐시 키로 캐시해서 간단하다.
'Spring > 모든 개발자를 위한 HTTP 웹 기본 지식' 카테고리의 다른 글
[HTTP] 3. HTTP 기본 (0) | 2024.01.11 |
---|---|
[HTTP] 2. URI와 웹 브라우저 요청 흐름 (0) | 2024.01.11 |
[HTTP] 1. 인터넷 네트워크 (1) | 2024.01.11 |