👨🏻💻 8개밖에 없는 메서드
메서드 | 의미 |
---|
GET | 리소스 취득 |
POST | 서브 리소스의 작성, 리소스 데이터의 추가, 그 밖의 처리 |
PUT | 리소스의 갱신, 리소스 작성 |
DELETE | 리소스의 삭제 |
HEAD | 리소스의 헤더(메타 데이터) 취득 |
OPTIONS | 리소스가 서포트하는 메서드의 취득 |
TRACE | 자기 앞으로 요청 메시지를 반환(루프 백) 시험 |
CONNECT | 프록시 동작의 터널 접속으로 변경 |
👨🏻💻 HTTP 메서드와 CRUD
👨🏻💻 GET - 리소스의 취득
👨🏻💻 POST - 리소스의 작성, 추가
서버 리소스의 작성
- 어떤 리소스에 대한 서브 리소스의 작성
- 응답에는 201 Craeted 스테이터스 코드 반환
리소스에 데이터 추가
- 기존의 리소스에 데이터를 추가
- 해당 데이터를 리소스의 끝에 추가할지 처음에 추가할지는 서버의 구현에 의존합니다.
- 처음부터 어떤 리소스에 요청된 POST가 작성을 의미하는 것인지 데이터의 추가를 의미하는 것인지도 서버의 구현에 의존
다른 메서드로는 대응할 수 없는 처리
- 이론적으로는 URI의 길이를 제한하지 않지만 구현상 2,000자 등의 상한선이 존재
- URI가 긴 경우 GET 방식을 이용하기 보다는 POST 요청으로 바디에 URI에 포함시켰던 키워드를 포함시킵니다.
👨🏻💻 PUT - 리소스의 갱신, 작성
리소스의 갱신
- 리소스를 수정하는 역할을 담당하는데 PUT에 대한 응답은 바디에 결과를 넣어도 좋고, 바디에는 아무것도 넣지 않고 응답이 바디를 가지지 않는다는 것을 나타내는 204 No Content를 반환해도 좋습니다.
리소스의 작성
- 존재하지 않는 URI에 대한 요청이 들어올 경우 서버는 리소스를 새로 작성합니다.
- 클라이언트가 이미 리소스의 URI를 알고 있기 때문에 Location 헤더를 반환할 필요가 없습니다.
POST와 PUT의 구분
- 설계상 지침
- POST로 리소스를 작성할 경우
- 클라이언트는 리소스의 URI를 지정할 수 없고, URI의 결정권은 서버 측에
- PUT로 리소스를 작성할 경우
- 리소스의 URI는 클라이언트가 결정
- 리소스가 중복되어 덮어쓰기 되는 것을 방지하기 위해 클라이언트에서 사용 전에 URI의 존재를 체크해야만 합니다.
- 리소스의 작성은 POST로 수행하여 URI를 서버 측에서 결정하는 설계가 바람직
👨🏻💻 DELETE - 리소스의 삭제
- 일반적으로 응답은 바디를 가지지 않습니다.
- 응답의 스테이터스 코드에 바디가 없다는 의미의 204 No Content가 사용되는 경우도 있습니다.
👨🏻💻 HEAD - 리소스의 헤더 취득
- 리소스의 헤더(메타 데이터)만을 취득하는 메서드
- 네트워크의 대역을 절약하면서 리소스의 크기를 조사하거나, 리소스의 갱신인자를 구할 수 있습니다.
👨🏻💻 OPTIONS - 리소스가 서포트하는 메서드의 취득
- 그 리소스가 지원하고 있는 메서드의 목록을 반환
- OPTIONS 자체는
Allow 헤더
에 포함하지 않습니다.
- OPTIONS를 구현하는 경우, 많은 웹 애플리케이션 프레임워크에서는 리소스마다 대응하는 메서드를 반환하도록 직접 구현해야 합니다. 설정 파일 등을 통해
// 요청
OPTIONS /list HTTP/1.1
//응답
HTTP/1.1 200 OK
Allow: GET, HEAD, POST // 리소스가 허용하는 메서드의 목록
👨🏻💻 POST를 PUT/DELETE 대신 사용하는 방법
- 현실적으로 가장 많이 이용되고 있는 메서드는 GET과 POST 2가지
- HTML의 폼에서 지정할 수 있는 메서드가 GET과 POST뿐이라는 제한에서 기인
_method 파라미터
- 폼의 숨겨진 (hidden) 파라미터에 _method 라는 파라미터를 준비하고 그 곳에 원래 보내고 싶었던 메서드의 이름을 넣습니다.
- _method 파라미터는 Ruby on Rails가 채용
<form target="/List/item" action="POST">
<input type="hidden"id="_method"value="PUT">
<textrea id="body"> ... </textarea>
</form>
위와 같은 폼 전송 시 다음의 요청이 보내집니다.
POST /list/item1 HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
_method=PUT&body=...
- 바디에는 폼에서 입력된 항목을 URI의 쿼리 파라미터와 같은 스펙으로 인코딩한 텍스트가 들어 있습니다.
- Content-Type 헤더의 값 application/x-www-form-urlencoded는 이 포맷을 나타내는 미디어 타입
웹 애플리케이션 프레임워크 등의 서버 측 구현에선 _method 파라미터를 보고 이 요청 자체를 PUT으로서 다룹니다.
X-HTTP-Method-Override
웹 애플리케이션 프레임워크 등의 서버 측 구현은 X-HTTP-Method-Override 헤더를 보고, 이 요청을 PUT으로 취급
👨🏻💻 조건부 요청
조건부 요청이란?
- HTTP 메서드와 갱신일자 등으로 헤더를 구성하면 메서드의 실행 여부를 리소스의 갱신일자를 조건으로 서버가 선택할 수 있습니다. 이러한 요청을 가리킴
👨🏻💻 멱등성과 안전성
통신 에러가 발생했을 떄 요청을 어떻게 회복할 것인가?
멱등성이란?
- 어떤 조작을 몇 번을 반복해도 결과가 동일한 것
- PUT과 DELETE는 멱등이므로, PUT이나 DELETE를 같은 리소스에 몇 번을 실행해도 반드시 같은 결과(리소스의 내용이 갱신되어 있다. 리소스가 삭제되어 있다)를 얻을 수 있음
안전성이란?
- 조작 대상의 리소스의 상태를 변화시키지 않는 것
메서드 | 성질 |
---|
GET, HEAD | 멱등이고 안전하다 |
PUT, DELETE | 멱등이지만 안전하지 않다 |
POST | 멱등이지도 안전하지도 않다 |
- 리소스의 상태에 변화를 부여하는 것을 부작용이라고 함. 안전 → 조작 대상인 리소스에 부작용이 없는 것
👨🏻💻 메서드의 오용
- 웹 서비스와 웹 API의 설계를 잘못하면 메서드가 안전하지 않게 되거나 멱등이 아니게 될 가능성도 존재
GET이 안전하지 않게 되는 예
- GET으로 리소스를 변경하거나 리소스를 삭제하는 것은 GET의 잘못된 사용방법
- GET의 실행 전후에 리소스에 변경이 가해져 있는지 여부로 GET의 올바른 사용을 판단
다른 메서드로 할 수 있는데 POST를 오용한 예
- 적절한 메서드가 마련되어 있는데도 불구하고, POST로 그 기능을 실현하는 사용방법
- XML-RPC와 SOAP
- 둘 다 RPC를 구현하기 위한 프로토콜이지만, 모든 함수 호출을 POST로 구현하도록 설계
PUT이 멱등이 아니게 되는 예
- PUT으로 리소스의 내용의 상대적인 차분으로 전송한 경우
- PUT으로는 그 리소스의 완전한 표현을 전송하도록 합니다.
DELETE가 멱등이 아니게 되는 예
- 소프트웨어의 최신 버전을 나타내는 http://example.com/latest 라는 에일리어스 리소스를 삭제하는 예
- 에일리어스 리소스와 같은 특수한 리소스는 특별한 이유가 없는 한, 갱신과 삭제 등의 조작을 할 수 없도록 설계
👨🏻💻 웹의 성공 이유는 HTTP 메서드에 있다
- 메서드를 한정적으로 고정시켰기 때문에 프로토콜이 심플하게 유지되었고 웹은 성공했습니다.