HTTP 메서드 완전정복

GET과 POST만 알던 사람도 PUT, PATCH, DELETE를 왜 나눠 쓰는지 이해할 수 있도록, 메서드의 뜻과 '안전·멱등' 개념, 실제 사고 사례를 차례로 풀어 봅니다.

한눈에 보기

HTTP 메서드는 브라우저나 앱이 서버에 보내는 요청 맨 앞에 붙는 '동사'입니다. 같은 주소(URL)라도 GET으로 부르면 조회, DELETE로 부르면 삭제처럼 서버에 전하는 의도가 달라집니다. 이 구분은 단순한 관습이 아니라 캐시, 재시도, 크롤러, 브라우저 보안 규칙이 모두 메서드의 성격(안전한가, 반복해도 같은가)에 기대어 동작하기 때문에 중요합니다. 이 글은 일곱 가지 메서드의 역할, 메서드가 늘어난 과정, 그리고 실제로 메서드 선택이 문제가 된 사례를 다룹니다.

이 글은 MDN, IETF RFC 문서 등 공개 자료를 바탕으로 한 일반 정보이며, 실제 API 설계는 사용하는 서비스의 문서를 우선 확인하세요.

메서드는 어떻게 늘어났나: 짧은 역사

위키백과의 HTTP 항목에 따르면 1990년 처음 가동된 웹 서버는 GET 메서드만 썼고, 1991년의 첫 문서화 버전인 HTTP/0.9도 GET만 지원했습니다. 1996년 5월 RFC 1945로 정리된 HTTP/1.0에는 GET, HEAD, POST가 들어갔고(PUT, DELETE 등은 부가 메서드로 언급), 1997년 1월 RFC 2068로 공개된 HTTP/1.1에서 PUT, DELETE, CONNECT, OPTIONS, TRACE가 정식 목록에 오릅니다. PATCH는 이보다 한참 뒤인 2010년 3월 RFC 5789(저자 Lisa Dusseault, James Snell)에서 추가되었습니다. 2022년 6월에 나온 RFC 9110 'HTTP Semantics'는 흩어져 있던 여러 RFC(7230~7235 계열 등)를 정리·대체한 문서로, 현재 메서드의 의미는 이 문서와 MDN 같은 해설을 기준으로 읽는 것이 좋습니다.

메서드별 역할 정리

아래 카드는 일곱 가지 메서드를 한 줄씩 정리한 것입니다. 이어지는 표와 사례에서 같은 메서드를 다른 각도로 다시 만나게 됩니다.

🌐

GET

서버로부터 데이터를 조회할 때 사용하는 메서드로, 웹페이지를 열람할 때 가장 흔하게 발생하는 요청입니다.

🌐

POST

서버에 새로운 데이터를 생성하거나 제출할 때 사용하는 메서드로, 회원가입이나 게시글 작성에 주로 쓰입니다.

🌐

PUT

기존 데이터 전체를 새로운 내용으로 완전히 교체할 때 사용하는 메서드입니다.

🌐

PATCH

PUT과 달리 데이터의 일부분만 수정할 때 사용하는 메서드입니다.

🌐

DELETE

서버에 있는 특정 데이터를 삭제할 때 사용하는 메서드입니다.

🌐

OPTIONS

서버가 어떤 메서드와 기능을 지원하는지 미리 확인할 때 사용하는 메서드입니다.

웹의 모든 요청은 이 동사들로 이루어집니다

웹브라우저와 서버가 데이터를 주고받을 때는 항상 이 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 설계·사용 체크리스트

가상 예시: 결제 요청을 두 번 보낸 경우

(가상 예시) 쇼핑 앱에서 '주문하기' 버튼을 누르자 응답이 늦어 사용자가 다시 눌렀다고 합시다. 주문 생성을 POST로 받았다면 서버는 같은 요청을 두 건의 주문으로 처리할 수 있습니다. 반면 클라이언트가 주문 번호를 미리 정해 'PUT /orders/주문번호'로 보냈다면, 같은 요청이 두 번 와도 그 번호의 주문 한 건이 같은 상태로 남습니다. 현실의 서비스는 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 사전 요청입니다. 서버가 허용 메서드와 헤더로 응답하면 본 요청이 이어서 전송됩니다.

멱등성이 왜 중요한가요?

네트워크 오류로 응답을 못 받았을 때 같은 요청을 다시 보내도 결과가 어긋나지 않는지를 판단하는 기준이 되기 때문입니다. 멱등한 메서드는 재시도가 비교적 안전하고, 그렇지 않은 메서드는 중복 처리를 막는 장치가 따로 필요할 수 있습니다.

이어서 읽어 보세요