후라이
[HTTP] HTTP Method 본문
1.회원 정보 관리 API를 만들어라.
- 회원 목록 조회
- 회원 조회
- 회원 등록
- 회원 수정
- 회원 삭제
<Before>
- 회원 목록 조회 /read-member-list
- 회원 조회 /read-member-by-id
- 회원 등록 /create-member
- 회원 수정 /update-member
- 회원 삭제 /delete-member
이렇게 설계하면 어떨까..? > 안된다
가장 중요한 것은, 리소스를 식별하는 것이다.
회원을 조회하고, 등록하고, 수정하고, 삭제하는 것은 리소스가 아니다. 바로 "회원" 그 자체가 리소스이다.
엇, 그럼 다 member인데..? >> 맞다. 회원이라는 리소스만을 식별하되 회원 리소스를 URI에 매핑하면된다.
<After>
- 회원 목록 조회 /members
- 회원 조회 /members/{id}
- 회원 등록 /members/{id}
- 회원 수정 /members/{id}
- 회원 삭제 /members/{id}
엥....? 그럼 조회, 등록, 수정, 삭제 등의 행위를 어떻게 구별하나?
이를 구별하기 위해 HTTP Method를 사용하는 것이다!
Major method
• GET: 리소스 조회
• POST: 요청 데이터 처리, 주로 등록에 사용
• PUT: 리소스를 대체, 해당 리소스가 없으면 생성
• PATCH: 리소스 부분 변경
• DELETE: 리소스 삭제
Minor method
• HEAD: GET과 동일하지만 메시지 부분을 제외하고 상태 줄과 헤더만 반환
• OPTIONS: 대상 리소스에 대한 통신 가능 옵션(메서드)을 설명(주로 CORS에서 사용)
• CONNECT: 대상 리소스로 식별되는 서버에 대한 터널을 설정
• TRACE: 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행
2. GET
- 리소스를 조회한다.
- 서버에 전달하고 싶은 데이터는 query를 통해서 전달한다.
GET /search?q=hello&hl=ko HTTP/1.1
Host: http://www.google.com - 메시지 바디를 통해 데이터를 전달할 수는 있는데, 데이터 전달 용도로는 잘 안 쓴다..!
위 그림처럼, 클라이언트가 /members/100의 리소스를 조회한다고 하자.
서버는 그럼 /members/100에 위와 같이 username이 "young"이고 나이가 20인 데이터를 가지고 있다.
GET 요청 메시지가 서버에게 도달하고 나면, 당연히 서버에서는 응답 메시지를 보낼 것이다.
바로 이렇게 전달하고자 하는 데이터를 응답 메시지의 body에 잘 담아서 말이다.
어렵지 않다! 이전에 HTTP Message 게시글에서 봤듯, 메시지 형식에 맞게 잘 도착했음을 알 수 있다.
3. POST
- 요청 데이터를 처리한다.
- 메시지 바디를 통해 서버로 요청 데이터를 전달할 수 있다.
- 서버는 요청 데이터를 처리한다.
메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행한다. - 주로 전달된 데이터로 신규 리소스 등록, 프로세스 처리 등을 다룬다.
클라이언트가 서버에게 POST 메서드를 사용해 /members에 body에 담긴 데이터를 등록하고자 한다.
(회원가입 정도로 이해하면 되겠다)
그럼 서버는 실제로 /members/100 이라는 식별자를 임명하여 해당 데이터를 생성한다.
그리고 마지막으로 잘 생성했다는 201 Created 응답 메시지를 보내며,
Location: /members/100으로 저장된 location까지 알려준다.
그런데, POST는 단순히 "등록"만 처리하는 것이 아니라
Body에 담긴 모든 요청 데이터를 처리한다. 여기서 요청 데이터를 어떻게 처리한다는 말인가?
- HTML form에 입력한 정보로 회원 가입, 주문 등
- 게시판 글쓰기, 댓글 달기
- 신규 주문 생성
- 한 문서 끝에 내용 추가하기
>> 이와 같은 예시처럼 이 리소스 URI에 POST 요청이 들어오면 요청 데이터를 어떻게 처리할지 리소스마다 따로 정해야 한다.
1. 새 리소스 생성(등록)
: 서버가 아직 식별하지 않은 새 리소스 생성
2. 요청 데이터 처리
: - 단순한 데이터 생성, 변경, 더 나아가 프로세스 처리까지
ex) 주문에서 결제 완료-> 배달 시작 -> 배달 완료 처럼 단순히 값 변경을 넘어 프로스세의 상태가 변경되는 경우
- POST의 결과로 새로운 리소스가 생성되지 않을 수도 있음(꼭 생성이 아니라 control할 수도 있다는 뜻)
3. 다른 메서드로 처리하기 애매한 경우
ex) JSON으로 조회 데이터를 넘겨야 하는데, GET 메서드를 사용하기 어려운 경우
결론적으로, 애매하면 POST를 쓰면 된다.
4. PUT
- 리소스가 없으면 새로 생성한다 (=POST)
- 리소스가 있으면 "완전히" 대체한다 (덮어쓰기)
- 클라이언트가 리소스를 식별한다. (클라이언트가 리소스의 위치를 알고 있다는 뜻)
4.1) 리소스가 있는 경우
일단 request 메시지를 보면 PUT /members/100 이라고 써진 시작 라인이 보일 것이다.
위에 쓴 특징처럼, PUT 메서드는 요청을 보내는 클라이언트가 생성하고자 하는 리소스의 정확한 위치를 알고 있다.
그런데, 오른쪽 서버를 보면 /members/100에는 이미 username:young이고 age:20인 리소스가 존재한다.
그럴 때에는 이렇게 클라이언트가 보낸 리소스로 완전히 대체된다.
여기서 주의할 점은 "완전히"이다.
내가 만약 PUT 요청으로 body에 "age":20만 보냈다고 하자. 그럼 서버에서 이를 처리할 때,
"username": "old",
"age": 20 이 아니라
"age": 20 으로 초기화된다.
즉, Body에 실어 보낸 정보로 그저 완전히 덮어쓰기 된다는 것이다.
4.2) 리소스가 없을 때
그림과 같이 /members/100에는 리소스가 없으며, 이 상태에서 PUT 요청이 들어오면
POST에서와 동일하게, 새로운 리소스가 만들어진다.
5. PATCH
- 리소스가 부분 변경이 된다.
앞서 봤던 PUT 메서드는 리소스의 부분 변경이 불가능하다.
하지만 PATCH 메서드는 부분 변경이 가능하여, age:50에 대해서만 변경하고, username:young도 유지된다.
(단, PATCH 메서드가 지원되지 않는 서버도 있다. 그럴 땐 POST를 쓰면 된다. )
6. DELETE
- 단순하다. 리소스를 삭제하는 메서드이다.
멱등 메서드의 의미에 대해 정확히 짚고 넘어가자.
사전적 의미와 동일하다. 내가 이 메서드를 한 번 호출하든 두 번 호출하든, 100번을 호출해도 결과는 동일해야 한다.
- GET : 한 번 조회하든, 두 번 조회하든 항상 조회되는 결과는 동일하다.
- PUT : 내가 한 번 PUT하든 두 번 PUT하든, 항상 "완전히" 덮어쓰기 된다. (=결과는 동일하다)
- DELETE : 내가 한 번 삭제하든 두 번 삭제하든 항상 결과가 삭제되는 것은 동일하다.
- POST : 멱등이 아니다. 두 번 호출하면(두 번 생성하면) 결제가 여러번, 중복되는 경우가 발생할 수 있다.
(단, 여기서 멱등은 외부 요인에 의한 리소스의 변경을 고려하지는 않는다.)
멱등이라는 개념이 왜 필요하냐면,
만약 내가 DELETE request를 보냈는데 이 요청이 된 건지 안 된 건지 모를 때
확인 차 다시 보내려는 경우가 생길 수 있다. 이럴 때 멱등의 개념을 도입해 생각해 보는 것이다.
[참고] : 인프런-김영한 <모든 개발자를 위한 HTTP 웹 기본 지식>
'HTTP' 카테고리의 다른 글
[HTTP] HTTP 상태 코드 (2) | 2024.12.15 |
---|---|
[HTTP] HTTP 메서드 활용 | 정적 / 동적 데이터 | HTML Form | HTTP API (1) | 2024.12.15 |
[HTTP] 모든 것이 HTTP | HTTP Message (1) | 2024.12.12 |
[URI & 웹 브라우저 요청 흐름] (0) | 2024.12.11 |
[인터넷 네트워크] IP | TCP/UDP | PORT | DNS (1) | 2024.12.11 |