2025-09-22 01:25
-
HTTP 메서드는 클라이언트가 웹 서버에 요청하는 행동의 종류를 정의하는 약속이자 소통 방식임.
-
GET, POST, PUT, DELETE, PATCH 등은 각각 조회, 생성, 전체 수정, 삭제, 부분 수정이라는 명확한 역할을 수행하며, 이는 RESTful API 설계의 근간을 이룸.
-
안전성(요청이 서버의 상태를 바꾸는가)과 멱등성(요청을 여러 번 보내도 결과가 동일한가)의 개념을 이해하고 메서드를 올바르게 사용하는 것이 중요함.
웹 개발자라면 반드시 알아야 할 HTTP 메서드 완벽 정복 핸드북
우리가 매일같이 사용하는 월드 와이드 웹(World Wide Web)은 보이지 않는 수많은 약속 위에서 동작한다. 웹 브라우저(클라이언트)가 웹 서버에 “이 웹페이지를 보여줘”라고 요청하고, 서버는 “알겠어, 여기 데이터야”라고 응답하는 과정은 모두 **HTTP(HyperText Transfer Protocol)**라는 통신 규약에 따라 이루어진다. 이 거대한 통신 시스템의 핵심에는 바로 **HTTP 메서드(HTTP Methods)**가 자리 잡고 있다.
HTTP 메서드는 클라이언트가 서버에 무엇을 하고 싶은지를 명확하게 전달하는 ‘동사’와 같다. 단순히 데이터를 달라고 할 수도 있고, 새로운 데이터를 생성하거나, 기존 데이터를 수정 또는 삭제해달라고 요청할 수도 있다. 이 ‘동사’들을 얼마나 잘 이해하고 적재적소에 사용하느냐가 웹 서비스의 안정성과 확장성, 그리고 개발자 간의 소통 효율을 결정짓는다.
이 핸드북은 HTTP 메서드의 탄생 배경부터 각 메서드의 정확한 용도와 특징, 그리고 실무에서 자주 헷갈리는 개념들까지 깊이 있게 파고든다. 이 글을 끝까지 읽는다면, 당신은 웹의 동작 원리를 더 깊게 이해하고, 더 나은 RESTful API를 설계할 수 있는 튼튼한 기초를 다지게 될 것이다.
1. 만들어진 이유 웹의 소통 방식을 정의하다
1990년대 초, 팀 버너스리가 웹을 처음 고안했을 때, 그는 분산된 컴퓨터들 사이에 있는 하이퍼텍스트 문서를 어떻게 주고받을지에 대한 표준화된 방법이 필요했다. 이때 탄생한 것이 바로 HTTP다.
이것을 식당에 비유해 보자.
-
클라이언트(손님): 식당에 와서 음식을 주문하는 주체.
-
서버(주방): 손님의 주문을 받아 음식을 만들어 내어주는 주체.
손님이 주방에 주문하려면 ‘주문서’가 필요하다. 이 주문서가 바로 **HTTP 요청 메시지(HTTP Request Message)**다. 손님은 주문서에 “파스타 하나 주세요”라고 적을 것이다. 여기서 “주세요”라는 행위의 종류가 바로 HTTP 메서드에 해당한다.
만약 모든 요청이 단순히 “요청합니다”라는 한 가지 방식으로만 이루어진다면 주방은 혼란에 빠질 것이다. 이것이 음식을 달라는 것인지, 예약을 하려는 것인지, 아니면 주문을 취소하려는 것인지 알 수 없기 때문이다. 따라서 HTTP는 요청의 의도를 명확히 하기 위해 다음과 같은 다양한 ‘동사’, 즉 메서드를 정의했다.
-
GET: 메뉴판(데이터)을 보여줘.
-
POST: 새로운 주문(데이터)을 접수해 줘.
-
PUT: 기존 주문(데이터) 내용을 다른 것으로 바꿔줘.
-
DELETE: 주문(데이터)을 취소해 줘.
이처럼 HTTP 메서드는 클라이언트와 서버 간의 명확하고 예측 가능한 소통을 위해 만들어졌다. 개발자는 특정 메서드를 보면 서버에서 어떤 일이 일어날지 예측할 수 있어야 하며, 이것이 바로 잘 설계된 웹 아키텍처의 시작이다.
2. 핵심 HTTP 메서드 파헤치기 CRUD의 네 기둥
데이터를 다루는 대부분의 애플리케이션은 **CRUD(Create, Read, Update, Delete)**라는 네 가지 기본 기능을 기반으로 한다. HTTP 메서드는 이 CRUD 작업에 각각 매핑되는 핵심적인 메서드들을 제공한다.
GET (조회): 정보를 가져오다
GET 메서드는 가장 흔하고 기본적인 메서드로, 특정 리소스(Resource)의 조회를 요청한다. 즉, 서버에게 데이터를 달라고 요청하는 것이다. 웹 브라우저의 주소창에 URL을 입력하고 엔터를 치면, 브라우저는 해당 URL의 서버에 GET 요청을 보내 웹페이지를 받아온다.
-
주요 역할: 데이터 조회 (Read)
-
특징:
-
안전(Safe):
GET요청은 서버의 상태를 변경해서는 안 된다. 단순히 데이터를 읽어오기만 해야 한다. -
멱등(Idempotent): 동일한
GET요청을 여러 번 보내도 서버의 상태는 변하지 않으며, 매번 같은 결과(또는 동일한 의미의 결과)를 반환해야 한다. -
캐시 가능(Cacheable):
GET요청의 결과는 캐시될 수 있다. 브라우저는 한 번 받아온 이미지나 CSS 파일을 캐시에 저장해두었다가 다음 요청 시 서버에 다시 요청하지 않고 캐시된 데이터를 사용함으로써 로딩 속도를 높인다. -
요청에 본문(Body)이 없음: 필요한 데이터는 URL의 쿼리 스트링(Query String)을 통해 전달한다. 예:
/users?id=123
-
사용 예시:
-
GET /users: 모든 사용자 목록을 조회 -
GET /users/123: ID가 123인 특정 사용자의 정보를 조회
POST (생성): 새로운 것을 만들다
POST 메서드는 서버에 새로운 리소스를 생성해달라고 요청할 때 사용된다. 게시판에 새 글을 작성하거나, 회원가입 폼을 제출하는 등의 작업이 POST를 통해 이루어진다. GET과 달리 요청에 **본문(Body)**이 포함되며, 이 본문에 생성할 데이터의 정보를 담아 서버로 전송한다.
-
주요 역할: 데이터 생성 (Create)
-
특징:
-
안전하지 않음(Not Safe):
POST요청은 서버에 새로운 리소스를 생성하므로 서버의 상태를 변경시킨다. -
멱등하지 않음(Not Idempotent): 동일한
POST요청을 여러 번 보내면, 일반적으로는 여러 개의 새로운 리소스가 생성된다. (예: 글쓰기 버튼을 여러 번 누르면 같은 내용의 글이 여러 개 작성됨) -
요청에 본문(Body)이 있음: 생성할 데이터를 요청 본문에 담아 전송한다.
-
사용 예시:
POST /users: 요청 본문에 담긴 정보로 새로운 사용자를 생성
PUT (전체 수정): 완전히 대체하다
PUT 메서드는 특정 리소스를 전체적으로 교체할 때 사용된다. 만약 리소스가 존재하지 않으면 새로 생성하고, 존재하면 완전히 덮어쓴다. 즉, 요청 본문에 담긴 내용으로 지정된 리소스의 모든 데이터를 대체하는 것이다.
-
주요 역할: 데이터 전체 수정 (Update) 또는 생성
-
특징:
-
안전하지 않음(Not Safe): 서버의 리소스를 수정하므로 상태를 변경시킨다.
-
멱등(Idempotent): 동일한
PUT요청을 여러 번 보내도 결과는 항상 동일하다. 예를 들어, 사용자 ID 123의 이름을 “Alice”로 바꾸는PUT요청을 100번 보내도 최종 결과는 ID 123의 이름이 “Alice”인 상태 하나뿐이다. -
클라이언트가 리소스 위치를 알고 있음:
PUT은/users/123과 같이 수정할 리소스의 정확한 URI를 지정해야 한다.
-
사용 예시:
PUT /users/123: ID가 123인 사용자의 정보를 요청 본문의 내용으로 완전히 덮어쓴다. 만약 요청 본문에email필드를 빼고 보내면, 해당 사용자의email정보는 삭제될 수 있다.
DELETE (삭제): 흔적도 없이 지우다
DELETE 메서드는 이름 그대로 특정 리소스를 삭제할 때 사용된다.
-
주요 역할: 데이터 삭제 (Delete)
-
특징:
-
안전하지 않음(Not Safe): 서버의 리소스를 삭제하므로 상태를 변경시킨다.
-
멱등(Idempotent): 동일한
DELETE요청을 여러 번 보내도 결과는 동일하다. 첫 번째 요청에서 리소스가 삭제되고, 이후의 요청들은 “이미 삭제되었음(404 Not Found)“을 응답할 수 있지만, 서버의 최종 상태는 ‘해당 리소스가 없는 상태’로 동일하다.
-
사용 예시:
DELETE /users/123: ID가 123인 사용자를 삭제
3. 조연이지만 중요한 HTTP 메서드들
CRUD를 담당하는 네 가지 핵심 메서드 외에도, 웹 개발을 더욱 정교하게 만들어주는 중요한 메서드들이 있다.
PATCH (부분 수정): 필요한 부분만 고치다
PUT이 리소스 전체를 교체하는 ‘외과 수술’이라면, **PATCH**는 필요한 부분만 수정하는 ‘연고 바르기’와 같다. 리소스의 특정 필드 값만 변경하고 싶을 때 사용하며, 이는 네트워크 효율성 측면에서 매우 유리하다.
-
주요 역할: 데이터 부분 수정 (Partial Update)
-
PUT과의 차이점:-
PUT:/users/123에{"name": "Bob"}을 보내면, 기존 사용자의 다른 정보(예:email,age)는 모두 사라지고 이름만 “Bob”으로 남게 될 수 있다. -
PATCH:/users/123에{"name": "Bob"}을 보내면, 다른 정보는 그대로 유지된 채 이름만 “Bob”으로 변경된다.
-
-
특징:
-
안전하지 않음(Not Safe): 서버의 리소스를 수정한다.
-
멱등하지 않음(Not Idempotent):
PATCH는 멱등할 수도 있고, 아닐 수도 있다. 예를 들어, 특정 필드의 값을 바꾸는 요청은 멱등하지만, “계좌 잔액을 100원 증가시켜라”와 같은 요청은 여러 번 보내면 결과가 계속 달라지므로 멱등하지 않다.
-
사용 예시:
PATCH /users/123: ID가 123인 사용자의 이름만 “Charlie”로 변경
HEAD (정보만 확인): 머리만 살짝 보다
HEAD 메서드는 GET과 기능적으로 동일하지만, 응답으로 본문(Body)을 제외하고 헤더(Header) 정보만 받아온다는 점이 다르다.
-
용도:
-
본격적으로 데이터를 다운로드하기 전에 파일의 크기(
Content-Length헤더)를 확인하고 싶을 때 -
리소스가 존재하는지, 최근에 수정되었는지(
Last-Modified헤더) 등 메타데이터만 확인하고 싶을 때 -
이를 통해 불필요한 네트워크 트래픽을 줄일 수 있다.
-
OPTIONS (가능한 방법 문의): 무엇을 할 수 있나요?
OPTIONS 메서드는 특정 URL(리소스)에 대해 서버가 어떤 HTTP 메서드들을 지원하는지 물어볼 때 사용한다. 서버는 응답 헤더의 Allow 필드에 지원하는 메서드 목록(GET, POST, PUT 등)을 담아 응답한다.
-
주요 용도:
- CORS (Cross-Origin Resource Sharing): 다른 출처(도메인)의 리소스를 요청하기 전에, 브라우저가 본 요청을 보내도 안전한지 확인하기 위해 보내는 **사전 요청(Preflight Request)**에
OPTIONS메서드가 사용된다.
- CORS (Cross-Origin Resource Sharing): 다른 출처(도메인)의 리소스를 요청하기 전에, 브라우저가 본 요청을 보내도 안전한지 확인하기 위해 보내는 **사전 요청(Preflight Request)**에
4. 심화 학습 RESTful API 설계의 핵심 개념
HTTP 메서드를 제대로 이해하기 위해서는 **안전성(Safety)**과 **멱등성(Idempotency)**이라는 두 가지 중요한 속성을 반드시 알아야 한다. 이는 단순히 기술적인 개념을 넘어, 예측 가능하고 안정적인 API를 설계하는 철학적 기반이 된다.
안전성 (Safety): 이 요청은 서버를 바꾸지 않아!
메서드가 **안전하다(Safe)**는 것은 해당 요청을 보냈을 때 서버의 리소스 상태에 어떠한 의도적인 변화도 일으키지 않는다는 의미다. 즉, ‘읽기 전용(Read-only)’ 작업이라고 생각할 수 있다.
-
안전한 메서드:
GET,HEAD,OPTIONS -
왜 중요한가?
-
웹 크롤러나 검색 엔진 봇이 웹 페이지를 수집할 때 안심하고
GET요청을 보낼 수 있다. 만약GET요청이 데이터를 삭제하는 기능이라면, 검색 엔진이 사이트를 방문할 때마다 데이터가 사라지는 끔찍한 일이 발생할 것이다. -
브라우저는 사용자가 뒤로가기/앞으로가기 버튼을 누르거나 페이지를 새로고침할 때
GET요청을 재전송하는 경우가 많은데, 이때 서버의 상태가 변하지 않으므로 안전하다.
-
⚠️ 주의: 안전성은 규약일 뿐, 강제적인 규칙은 아니다. 개발자가
GET요청에 데이터 삭제 기능을 구현하는 것도 기술적으로는 가능하다. 하지만 이는 HTTP 명세를 위반하는 행위이며, 심각한 부작용을 초래할 수 있으므로 절대 그렇게 해서는 안 된다.
멱등성 (Idempotency): 여러 번 호출해도 결과는 같아!
메서드가 **멱등하다(Idempotent)**는 것은 동일한 요청을 한 번 보내는 것과 여러 번 연속해서 보내는 것이 서버에 미치는 최종 결과가 같다는 것을 의미한다.
-
멱등한 메서드:
GET,PUT,DELETE,HEAD,OPTIONS -
멱등하지 않은 메서드:
POST,PATCH(멱등할 수도 있지만, 보장되지 않음)
엘리베이터 비유:
-
멱등한 행위: ‘3층’ 버튼 누르기. 한 번 누르든 열 번 누르든, 결과는 ‘엘리베이터가 3층으로 간다’는 것 하나로 동일하다.
-
멱등하지 않은 행위: ‘문 열림’ 버튼 누르기. 누를 때마다 문이 열려 있는 시간이 연장되므로, 누르는 횟수에 따라 결과가 달라진다.
왜 중요한가?
-
클라이언트가 요청을 보낸 후 네트워크 문제로 응답을 받지 못했을 때, 멱등한 메서드는 아무런 걱정 없이 요청을 재시도할 수 있다. 예를 들어, 결제 시스템에서
PUT으로 주문 상태를 ‘결제 완료’로 변경하는 요청을 보냈는데 응답이 없다면, 클라이언트는 안심하고 같은 요청을 다시 보낼 수 있다. 결과는 어차피 ‘결제 완료’ 상태 하나이기 때문이다. -
반면,
POST로 주문을 생성하는 요청에 대한 응답을 받지 못해 재시도하면 중복 주문이 발생할 수 있다.
한눈에 보는 메서드별 특징 비교
| 메서드 | 주요 역할 | 안전성 (Safe) | 멱등성 (Idempotent) | 본문(Body) 사용 |
|---|---|---|---|---|
| GET | 리소스 조회 | O | O | X |
| POST | 리소스 생성 | X | X | O |
| PUT | 리소스 전체 교체 | X | O | O |
| DELETE | 리소스 삭제 | X | O | X (가능하지만 권장 안 함) |
| PATCH | 리소스 부분 수정 | X | X | O |
| HEAD | 리소스 헤더 조회 | O | O | X |
| OPTIONS | 지원 메서드 확인 | O | O | X |
5. 실전 Q&A 자주 헷갈리는 질문들
Q1: POST와 PUT, 둘 다 데이터를 수정하는 데 사용할 수 있지 않나요?
네, 기술적으로는 POST를 사용해 특정 리소스를 수정하는 로직을 구현할 수 있다. 하지만 이는 RESTful한 설계 원칙에 위배된다.
-
PUT은 멱등성을 보장한다: 수정 요청을 여러 번 보내도 서버의 상태는 동일하게 유지되므로 ‘수정’ 작업에 더 안전하고 적합하다. -
POST는 ‘부모’ 리소스 아래에 ‘자식’ 리소스를 생성하는 의미가 강하다:/users라는 컬렉션에 새로운 사용자를 추가하는 것이POST의 대표적인 사용례다. -
의미의 명확성:
PUT /users/123은 “ID 123번 사용자를 이 내용으로 교체하라”는 의미가 명확하지만,POST /users/123은 의미가 모호해진다.
결론: 리소스 수정에는 멱등성이 보장되고 의미가 명확한 PUT(전체 수정)이나 PATCH(부분 수정)를 사용하는 것이 올바른 설계다.
Q2: PUT과 PATCH, 실무에서는 무엇을 더 선호하나요?
정답은 없지만, 현대적인 API 설계에서는 PATCH가 더 선호되는 경향이 있다.
-
네트워크 효율성:
PATCH는 변경할 데이터만 보내므로 요청의 크기가 작다. 사용자의 프로필 사진만 변경하는데 사용자의 모든 정보를 담아PUT으로 보내는 것은 비효율적이다. -
안정성:
PUT은 클라이언트가 보내지 않은 필드를 누락된 것으로 간주하여 데이터를 삭제할 위험이 있지만,PATCH는 그런 위험이 적다.
다만, PATCH를 서버에서 구현하는 것이 PUT보다 조금 더 복잡할 수 있다. 그럼에도 불구하고 대부분의 경우 효율성과 안정성이라는 장점 때문에 PATCH를 사용하는 것이 좋다.
Q3: GET 요청의 URL 길이에 제한이 있나요? Body에 데이터를 담으면 안 되나요?
HTTP 명세 자체에는 URL 길이에 대한 제한이 없다. 하지만 브라우저나 웹 서버별로 구현상의 길이 제한이 존재한다(보통 수천 자). 따라서 매우 긴 데이터를 전달해야 할 때는 GET의 쿼리 스트링 방식이 적합하지 않을 수 있다.
그렇다고 GET 요청의 Body에 데이터를 담는 것은 권장되지 않는다. 명세상으로는 금지되어 있지 않지만, 대부분의 서버 구현체는 GET 요청의 Body를 무시하거나 오류로 처리한다. GET은 오직 리소스를 식별하는 URI와 헤더 정보만으로 동작하도록 설계되었기 때문이다. 복잡한 조회 조건이 필요하다면 POST를 사용하여 조회 기능을 구현하는 방법도 고려할 수 있지만, 이는 GET의 캐시 기능 등 장점을 포기하는 선택이 될 수 있다.
6. 맺음말 올바른 메서드 사용의 중요성
HTTP 메서드는 단순히 클라이언트의 요청을 구분하는 기술적인 표식이 아니다. 그것은 웹의 자원을 어떻게 다루고 상호작용할 것인지에 대한 설계 철학이자 개발자들 사이의 사회적 약속이다.
-
GET을 보았을 때, 개발자는 이 요청이 안전하게 여러 번 호출될 수 있음을 신뢰한다. -
PUT을 보았을 때, 개발자는 이 요청이 멱등성을 가지므로 재시도에 안전하다고 판단한다. -
POST를 보았을 때, 개발자는 이 요청이 새로운 무언가를 만들어낼 것이라고 예측한다.
이러한 약속을 지키며 API를 설계하면, 우리는 훨씬 더 예측 가능하고, 안정적이며, 유지보수하기 쉬운 시스템을 만들 수 있다. HTTP 메서드의 의미를 깊이 이해하고 올바르게 사용하는 것이 견고한 웹 애플리케이션을 만드는 개발자의 첫 번째 덕목이라 할 수 있을 것이다.