웹의 모든 요청은 이 동사들로 이루어집니다
웹브라우저와 서버가 데이터를 주고받을 때는 항상 이 HTTP 메서드 중 하나를 통해 "무엇을 하고 싶은지"를 전달합니다. GET은 조회, POST는 생성처럼 각 메서드가 명확한 역할을 가지고 있어 개발자들 사이의 공통 약속으로 사용됩니다.
한 장으로 비교: 안전한가, 반복해도 같은가
'안전(safe)'은 서버의 상태를 바꾸지 않는 읽기 전용 동작이라는 뜻이고, '멱등(idempotent)'은 같은 요청을 한 번 보내든 여러 번 보내든 서버에 남는 결과가 같다는 뜻입니다. MDN은 모든 안전한 메서드는 멱등하지만 모든 멱등 메서드가 안전한 것은 아니라고 설명하며, PUT과 DELETE를 그 예로 듭니다. 아래 표는 MDN의 메서드 참조표를 기준으로 정리했습니다.
| 메서드 | 안전 | 멱등 | 한 줄 설명(MDN 기준) |
|---|---|---|---|
| GET | 예 | 예 | 지정한 리소스의 표현을 요청한다. 데이터를 가져오기만 해야 한다. |
| HEAD | 예 | 예 | GET과 같지만 응답 본문 없이 헤더만 받는다. |
| POST | 아니오 | 아니오 | 대상 리소스에 데이터를 제출한다. 서버에 상태 변화나 부수 효과가 생기는 경우가 많다. |
| PUT | 아니오 | 예 | 대상 리소스의 현재 표현을 요청 내용으로 교체한다. |
| DELETE | 아니오 | 예 | 지정한 리소스를 삭제한다. |
| OPTIONS | 예 | 예 | 대상 리소스와의 통신 옵션을 알려 준다. |
| PATCH | 아니오 | 아니오 | 리소스에 부분 수정을 적용한다. |
PATCH를 정의한 RFC 5789는 PATCH가 "안전하지도 멱등하지도 않다"고 밝히면서도, 요청을 멱등하게 보낼 수는 있다고 덧붙입니다. 예를 들어 If-Match 헤더와 강한 ETag를 쓰는 조건부 요청으로 충돌을 막으라고 권장합니다. 또 PUT은 요청 본문이 '수정된 완성본'이고, PATCH는 '현재 상태를 새 상태로 바꾸는 지시문'이라는 차이가 있으며, 패치 내용이 교체할 데이터보다 크다면 PUT이 나을 수 있다고도 적습니다.
실제 사례
사례 1. 구글 웹 가속기가 '삭제' 링크를 눌러 버린 일 (2005, GET의 안전성)
2005년 5월 6일, 웹 앱 업체 37signals는 자사 블로그에 구글 웹 가속기(Google Web Accelerator)가 일으키는 문제를 경고하는 글을 올렸습니다. 이 브라우저 부가 프로그램은 사용자가 보는 페이지에 걸린 링크를 미리 불러와 속도를 높이려 했는데, 37signals 팀은 Backpack 서비스에서 페이지가 사라지는 현상을 겪고 나서야 원인을 찾았다고 적었습니다. 글은 이를 "구글이 페이지의 모든 링크를 클릭하는 것과 같다"고 표현했고, 자바스크립트 확인창을 띄워 둔 삭제 링크도 무시한 채 실행된다고 지적했습니다. 댓글에서는 데이터를 파괴하는 동작을 일반 링크(GET) 뒤에 두면 안 된다는 의견이 많았고, 현실에서는 삭제나 로그아웃을 GET으로 처리하는 앱이 많다는 반론도 있었습니다. 같은 글에는 구글이 문제를 고치는 업데이트를 냈다는 구글 측 댓글도 달렸습니다. 여기서 배울 점은 GET이 '안전하다'는 약속은 서버뿐 아니라 브라우저 확장, 크롤러, 프리패치가 모두 믿고 쓰는 전제라는 것입니다. MDN도 안전한 메서드이기에 브라우저가 프리패치할 수 있다고 설명하며, GET으로 상태를 바꾸지 않을 책임은 웹 서버가 아니라 애플리케이션에 있다고 적습니다.
사례 2. 브라우저가 몰래 보내는 OPTIONS: CORS 사전 요청 (현재의 표준 동작)
프런트엔드 개발자가 개발자 도구 네트워크 탭에서 내가 보내지 않은 OPTIONS 요청을 발견하고 놀라는 일이 흔한데, 이것이 CORS 사전 요청(preflight)입니다. MDN에 따르면 브라우저는 다른 출처로 보내는 요청이 '단순 요청'이 아니면 본 요청에 앞서 OPTIONS를 보내 서버가 허락하는지 확인합니다. 단순 요청은 메서드가 GET, HEAD, POST 중 하나이고 헤더와 Content-Type도 정해진 범위 안일 때뿐이라서, PUT, DELETE, PATCH는 거의 항상 사전 요청을 부릅니다. 사전 요청에는 Access-Control-Request-Method 헤더로 본 요청의 메서드가 담기고, 서버는 Access-Control-Allow-Methods 등의 헤더로 허용 범위를 답합니다. 서버가 허락하지 않으면 브라우저는 본 요청을 보내지 않습니다. 배울 점은 OPTIONS가 목록에만 있는 메서드가 아니라 브라우저의 교차 출처 보안과 맞물려 실제 요청 흐름에 끼어든다는 것이므로, 서버가 OPTIONS에 알맞게 응답하도록 설정해야 합니다.
사례 3. 부분 수정을 위해 2010년에 추가된 PATCH (표준의 사례)
RFC 5789는 PATCH를 도입한 이유를 이렇게 설명합니다. 당시 PUT은 전체 교체만 지원하는데 이를 부분 수정에 쓰면 프록시·캐시·클라이언트·서버를 혼란스럽게 할 수 있었고, POST는 이미 너무 다양한 용도로 쓰이는 데다 어떤 패치 형식을 지원하는지 알아낼 표준 방법이 없었습니다. 그래서 '부분 수정'이라는 의도를 직접 드러내는 새 메서드를 만든 것입니다. 이 사례에서 배울 수 있는 것은 메서드 목록이 완결된 것이 아니라, 실무의 불편이 쌓이면 표준이 보강된다는 점입니다. 다만 PATCH가 나온 뒤에도 많은 서비스는 팀 규약에 따라 PUT 하나로 수정을 처리하기도 해서, 문서를 먼저 확인해야 합니다.
직접 해보기: API 설계·사용 체크리스트
- 조회는 GET, 상태 변경은 GET 금지: 삭제·결제·로그아웃이 링크 하나로 실행되도록 만들지 않았는지 확인합니다.
- 재시도할 요청은 멱등한지 따져 보기: 네트워크가 끊겨 다시 보낼 때 PUT·DELETE는 같은 결과를 기대할 수 있지만, POST는 중복 생성될 수 있습니다.
- 브라우저 개발자 도구로 직접 보기: 네트워크 탭에서 요청 메서드 열과 상태 코드를 함께 보며, 폼 제출은 POST, 주소창 입력은 GET인지 확인해 봅니다.
- CORS 오류가 나면 OPTIONS부터: 서버가 OPTIONS 요청에 허용 메서드·헤더를 응답하는지 먼저 봅니다.
- 상태 코드와 짝으로 읽기: PUT은 새로 만들면 201, 기존을 교체하면 200 또는 204가 쓰이는 식으로 메서드와 응답 코드가 짝을 이룹니다(MDN 기준).
가상 예시: 결제 요청을 두 번 보낸 경우
(가상 예시) 쇼핑 앱에서 '주문하기' 버튼을 누르자 응답이 늦어 사용자가 다시 눌렀다고 합시다. 주문 생성을 POST로 받았다면 서버는 같은 요청을 두 건의 주문으로 처리할 수 있습니다. 반면 클라이언트가 주문 번호를 미리 정해 'PUT /orders/주문번호'로 보냈다면, 같은 요청이 두 번 와도 그 번호의 주문 한 건이 같은 상태로 남습니다. 현실의 서비스는 POST에 별도의 중복 방지 키를 쓰는 등 다른 방법도 쓰므로, 이 예시는 멱등성이 왜 필요한지 보여 주는 설명용입니다.
흔한 오해와 정정
- 오해: POST가 GET보다 보안이 좋다. 실제: '안전'은 서버 상태를 바꾸지 않는다는 뜻일 뿐 암호화나 비밀 보호와는 다른 개념입니다. 전송 내용 보호는 HTTPS 같은 별도 수단의 몫이므로, 메서드를 바꾼다고 보안이 저절로 생기지는 않습니다.
- 오해: 브라우저에서 PUT·DELETE도 쓴다. 실제: MDN은 브라우저가 사용자 동작으로는 PUT이나 DELETE를 쓰지 않고, HTML 폼에서도 허용되지 않으며 개발자가 fetch() 등으로 직접 지정한다고 설명합니다.
- 오해: DELETE를 두 번 보내면 두 번 삭제된다. 실제: 멱등성은 서버에 남는 상태에 대한 약속이라, 이미 지워진 뒤에는 상태가 그대로입니다. 두 번째 응답 코드는 구현에 따라 달라질 수 있습니다.
- 오해: PUT과 POST는 이름만 다른 같은 기능이다. 실제: MDN은 두 메서드의 차이를 멱등성으로 설명합니다. PUT은 반복해도 결과가 같고, POST는 반복하면 추가 효과가 생길 수 있습니다.
한계와 논쟁, 더 알아볼 점
메서드 의미는 규약일 뿐 서버가 강제하는 것이 아니라서, GET으로 데이터를 지우도록 만든 서버도 동작은 합니다. 규약을 지킬 책임은 애플리케이션 개발자에게 있습니다. DELETE 요청에 본문을 실을 수 있는지는 MDN이 '의미가 정의되어 있지 않고 서버에 따라 4xx로 거절될 수 있다'고 설명하는 영역이라 피하는 편이 무난합니다. 또 PUT과 PATCH 중 무엇으로 수정 API를 만들지는 표준이 정답을 주기보다 서비스 설계 철학에 가까워서, 사용하는 API의 문서를 따르는 것이 현실적입니다. HTTP/2, HTTP/3으로 전송 방식이 바뀌어도 메서드의 의미는 유지되므로 이 글의 내용은 버전과 무관하게 적용되지만, 세부 동작은 버전별 문서를 확인하세요.
HTTP 상태 코드도 궁금하다면
404나 500 같은 오류 코드가 궁금하다면 HTTP 상태 코드 완전정복도 확인해보세요.
자주 묻는 질문
PUT과 PATCH는 어떻게 다른가요?
PUT은 데이터 전체를 새로운 내용으로 통째로 교체하는 반면, PATCH는 변경하고 싶은 일부 항목만 부분적으로 수정한다는 차이가 있습니다.
웹페이지에 접속하는 것도 HTTP 메서드인가요?
네, 브라우저 주소창에 URL을 입력해 페이지를 여는 것은 대부분 GET 메서드를 사용해 서버에 해당 페이지 데이터를 요청하는 과정입니다.
HEAD는 어디에 쓰나요?
GET과 같은 응답 헤더를 받되 본문은 받지 않는 메서드입니다. 파일을 내려받기 전에 존재 여부나 헤더 정보를 가볍게 확인하고 싶을 때 쓸 수 있습니다.
개발자 도구에 내가 보내지 않은 OPTIONS 요청이 보이는 이유는 무엇인가요?
다른 출처로 PUT, DELETE, PATCH 같은 단순하지 않은 요청을 보낼 때 브라우저가 서버의 허락 여부를 먼저 묻는 CORS 사전 요청입니다. 서버가 허용 메서드와 헤더로 응답하면 본 요청이 이어서 전송됩니다.
멱등성이 왜 중요한가요?
네트워크 오류로 응답을 못 받았을 때 같은 요청을 다시 보내도 결과가 어긋나지 않는지를 판단하는 기준이 되기 때문입니다. 멱등한 메서드는 재시도가 비교적 안전하고, 그렇지 않은 메서드는 중복 처리를 막는 장치가 따로 필요할 수 있습니다.
이어서 읽어 보세요
- HTTP 상태 코드 완전정복: 메서드에 대한 서버의 응답을 읽는 법
- HTTP 프로토콜의 발전: 1.x에서 2, 3으로 이어진 흐름
- API란 무엇인가: 메서드가 쓰이는 API의 기본 개념
- Postman으로 API 요청 보내기: 메서드를 직접 바꿔 가며 실습하기