1. HTTP 메서드
📚 HTTP API
API URI를 설계할 때는 리소스와 행위를 분리하는 것이 중요하다!
회원 정보 관리 API를 만드는 예시로 알아보자.
👉 리소스?
회원을 등록하고 수정하고 조회하는 것이 아니라 회원 그 자체가 리소스이다.
URI는 회원 members 라는 리소스만 식별하면 된다.
- 회원 목록 조회
/members
- 회원 조회
/members/{id}
- 회원 등록
/members/{id}
- 회원 수정
/members/{id}
- 회원 삭제
/members/{id}
조회, 등록, 삭제, 수정 행위는 어떻게 구분할까? ⬇️
📚 HTTP 메서드
GET
- 리소스 조회
- 서버에 전달하고 싶은 데이터는 query를 통해 전달
POST
- 메시지 바디를 통해 서버로 요청 데이터 전달
- 서버는 요청 데이터 처리
- 주로 전달된 데이터는 신규 리소스 등록에 사용.
- 단순히 값 변경을 넘어 프로세스 상태가 변경되는 경우 사용
- 결제완료 -> 배달 시작 -> 배달 완료처럼
/orders/{orderId}/start-delivery
- 다른 메서드로 처리하기 애매한 경우 사용
- JSON으로 조회 데이터 넘겨야하는데 GET메서드 사용하기 어려운 경우
PUT
PATCH
DELETE
📚 HTTP 메서드의 속성
-
안전 (Safe Methods)
-
멱등 (Idempotent Methods)
- f(f(x)) = f(x) : 한 번 호출하든 두 번 호출하든 100번 호출하든 결과가 똑같다.
- GET, PUT, DELETE 는 멱등 메서드이지만 POST, PATCH는 아니다! 두 번 호출하면 같은 결제가 중복해서 발생할 수 있다.
- 안전성이 보장된 메서드는 멱등성도 보장하지만, 멱등성을 지닌 메서드가 항상 안전성을 보장하지는 않는다. 예를 들어 PUT과 DELETE는 멱등한 메서드지만 리소스에 변화를 일으키기 때문에 안전한 메서드는 아니다.
💡API 관점에서 본다면?
- 단순히 돌아온 값이 같을 뿐 아니라 서버 상태(DB)에도 영향을 미치지 않는다.
- 예를들어 멱등성이 보장되지 않은 결제 API라면 실제로 결제가 성공했는지 수동으로 확인해야 하고 + 확인해 보니 실제로 결제가 되지 않았다면 고객이 같은 결제를 다시 시도해야한다.
반면 결제 API가 멱등하다면 다시 같은 요청을 보내지 않고 전에 받지 못한 결과만 다시 받을 수 있을 때 편리하다. 또 실수로 중복 요청이 되더라도(일명 ‘따닥’) 실제로는 결제가 되지 않아서 안심하고 여러 번 요청할 수 있다.
-
캐시가능 (Cacheable Methods)
- GET, HEAD, POST, PATCH는 응답 결과 리소스를 캐시해서 사용해도 되지만 실제로 POST, PATCH는 본문 내용까지 캐시 키로 고려해야해서 구현 쉽지 않다.
2. HTTP 메서드 활용
✏️ 클라이언트에서 서버로 데이터 전송
👉 데이터 전달 방식은 크게 2가지로 나뉜다.
- 쿼리 파라미터를 통한 데이터 전송
- 메시지 바디를 통한 데이터 전송
- POST, PUT, PATCH
- 회원가입, 상품 주문, 리소스 등록, 리소스 변경
👉 크게 4가지 상황이 있다.
1. 정적 데이터 조회
- 이미지, 정적 테스트 문서 -> 일반적으로 쿼리 파라미터 X
2. 동적 데이터 조회
- 주로 검색 (게시판 목록에서 정렬 필터) -> 쿼리 파라미터 O
3. HTML FORM을 통한 데이터 전송
- POST, GET만 지원
- 회원 목록, 등록/수정 폼, 조회 -> GET
- 회원 등록, 수정, 삭제 -> POST
- multipart/form-data 다른 종류의 여러 파일과 폼의 내용 함께 전송 가능
4. HTTP API를 통한 데이터 전송
- 서버 to 서버/ 앱 클라이언트/ 웹 클라이언트
- POST,PUT, PATCH 메시지 바디를 통해 데이터 전송, GET 쿼리 파라미터로 데이터 전달
- Content-Type: application/json을 주로 사용
- HTML API는 Form이 아닌 거의 모든 통신을 말함
✏️ HTTP API 설계 예시
💡 POST
서버에서 리소스 uri를 생성하고 관리한다.
ex) 신규 등록 시 사용자 정보 전달하면 서버에서 정보 + 사용자 id를 만들어 DB에 저장하고 id룰 response한다. --> 컬렉션
💡Put
클라이언트가 리소스 uri를 알고 관리한다.
ex) 신규 파일 등록 시 어떤 파일인지 filename을 넘겨준다. --> 스토어
3. HTTP 상태 코드
클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능이다.
➡️ 2xx (Successful) : 요청 정상 처리
- 201 OK
- 201 Created 요청 성공해서 새로운 리소스 생성
- 202 Accpeted 요청이 접수 되었으나 처리 완료 X ----> ex) 배치 처리
- 204 No Content 요청 성공 But 응답 X ----> ex) save 버튼
➡️ 3xx (Redirection) : 요청을 완료하려면 추가 행동이 필요
‼️리다이렉션
리다이렉션 3가지 종류
👉 (1) 영구 리다이렉션
: 리소스 URL이 영구적으로 이동
- 301 Moved Permanently
- 리다이렉트시 요청 메서드가 GET으로 변하고 본문이 제거될 수 있음(MAY)
- 308 Permanent Redirect
- 301과 기능은 같지만 리다이렉트시 요청 메서드와 본문 유지(처음 POST를 보내면 리다이렉트도 POST 유지)
301은 Get으로 바뀌고 바디 내용이 다 지워지기 때문에 308로 해결하는데 사실 실무에서는 /event -> /new-event로 바뀌면 요청 양식도 대부분 바뀌는 경우가 많아서 301을 사용한다.
👉 (2) 일시적인 리다이렉션
: 리소스 URI가 일시적으로 변경, 즉 URL을 마음대로 변경하면 안됨
- 302 Found
- 리다이렉트시 요청 메서드가 GET으로 변하고 본문이 제거될 수 있음(MAY)
- 307 Temporary Redirect
- 302와 기능은 같지만 리다이렉트시 요청 메서드와 본문 유지 필수!!
- 303 See Other
- 302와 기능은 같지만 요청 메서드가 GET으로 변경
‼️PRG: Post/Redirect/Get
POST로 주문 후 웹 브라우저를 새로고침하면 다시 요청되어 중복 주문이 될 수 있다.
POST로 주문 후에 주문 결과 화면을 GET 메서드로 리다이렉트한다면 새로고침을 해도 결과 화면을 GET으로 조회하기 때문에 중복 문제를 해결할 수 있다.

👉 (3) 기타 리다이렉션
- 300 Multiple Choices: 안씀
- 304 Not Modified
- 클라이언트에게 리소스 수정되지 않았음을 알려줌 즉, 캐시로 리다이렉트 -> 다음 글에서!
- 304 응답은 응답에 바디 메시지 포함 x (로컬 캐시 사용)
➡️ 4xx (Client Error): 클라이언트 오류
➡️ 5xx (Server Error): 서버 오류
- 500 Internal Server Error
- 503 Service Unavailable
- 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없음
- Retry-After 헤더 필드로 얼마뒤에 복구되는지 보낼 수도 있음 -> 다음 글에서!
20세 이상 허용이되는데 15세가 들어오거나, 잔액이 부족한 경우는 500에러를 내면 안됨!! 주의!!
Nullexception, DB 접근불가 등 정말 서버에 문제가 있을 때만 5xx 생성하기!
💡 위 글에서 언급한 상태코드 외에 클라이언트가 인식할 수 없는 상태코드를 서버가 반환하면 상위코드로 해석하면 된다.