HTTP 메서드
클라이언트가 서버에게 "무엇을 하고 싶은지" 알려주는 동사
주요 메서드 한눈에
| 메서드 | 용도 | 멱등성 | 안전성 |
|---|
| GET | 조회 | 예 | 예 |
| POST | 생성 | 아니오 | 아니오 |
| PUT | 전체 수정 | 예 | 아니오 |
| PATCH | 부분 수정 | 아니오 | 아니오 |
| DELETE | 삭제 | 예 | 아니오 |
멱등성(Idempotent)이란?
같은 요청을 여러 번 보내도 결과가 같음
GET /users/1 → 항상 같은 유저 반환
DELETE /users/1 → 첫번째: 삭제, 두번째: 404
(서버 상태는 동일 → 멱등)
POST /users → 매번 새 유저 생성
CRUD 매핑
Create → POST /users
Read → GET /users (목록)
GET /users/1 (상세)
Update → PUT /users/1 (전체)
PATCH /users/1 (부분)
Delete → DELETE /users/1
PUT vs PATCH
// 원본 데이터
{ "name": "Kim", "age": 25, "email": "k@a.com" }
// PUT /users/1 (전체 교체)
{ "name": "Kim", "age": 26, "email": "k@a.com" }
// 빠진 필드는 null/삭제됨
// PATCH /users/1 (부분 수정)
{ "age": 26 }
// 나머지 필드 유지
요청 본문(Body) 포함 여부
| 메서드 | Body | 예시 |
|---|
| GET | 없음 | 쿼리스트링 사용 |
| POST | 있음 | JSON 데이터 |
| PUT | 있음 | 전체 리소스 |
| PATCH | 있음 | 변경 부분만 |
| DELETE | 보통 없음 | (필요시 사용) |
실무 패턴
| 상황 | 메서드 |
|---|
| 검색/필터링 | GET + 쿼리스트링 |
| 파일 업로드 | POST + multipart |
| 비밀번호 변경 | PATCH |
| 소프트 삭제 | PATCH (status=deleted) |
| 하드 삭제 | DELETE |
| 결제 요청 | POST (멱등키 헤더 포함) |
Q.GET과 POST의 차이를 설명해주세요.
의도와 성질이 다릅니다. 데이터 위치는 결과일 뿐입니다.
| 항목 | GET | POST |
|---|
| 의도 | 조회 | 생성이나 처리 요청 |
| 안전성 | 안전하다. 상태를 바꾸지 않는다 | 바꾼다 |
| 멱등성 | 있다 | 없다 |
| 캐시 | 가능하다 | 기본적으로 안 된다 |
| 데이터 위치 | 주로 쿼리 문자열 | 주로 본문 |
| 브라우저 재요청 | 그냥 다시 보낸다 | 확인을 묻는다 |
중요한 것은 상태를 바꾸는 동작을 GET 에 두지 않는 것입니다. 크롤러가 링크를 훑거나 브라우저가 미리 불러오면 의도 없이 실행됩니다. SameSite 쿠키도 최상위 GET 이동에는 쿠키를 실어 CSRF 경로가 됩니다.
흔한 실수: "GET 은 길이 제한이 있고 보안에 약하다"로만 답하는 것. 길이 제한은 구현 사항이고, 쿼리 문자열도 HTTPS 면 암호화됩니다. 다만 서버 로그와 리퍼러에 남는 점은 사실입니다.
Q.PUT과 PATCH의 차이는 무엇인가요?
전체를 바꾸는지 일부만 바꾸는지가 다릅니다.
| 항목 | PUT | PATCH |
|---|
| 의미 | 리소스를 이 내용으로 대체 | 이 부분만 수정 |
| 보내는 것 | 전체 표현 | 변경분 |
| 멱등성 | 있다 | 구현에 따라 다르다 |
| 생략한 필드 | 비워지거나 기본값이 된다 | 그대로 유지된다 |
현재 값이 { "name": "홍길동", "email": "a@b.c", "phone": "010" } 이라고 해봅시다.
| 요청 | 보낸 것 | 결과 |
|---|
| PUT | { "name": "김철수" } | email 과 phone 이 사라질 수 있다 |
| PATCH | { "name": "김철수" } | name 만 바뀐다 |
PATCH 가 멱등하지 않을 수 있는 이유는 "수량을 1 증가"처럼 상대적 변경을 표현할 수 있기 때문입니다. 같은 요청을 두 번 보내면 결과가 다릅니다.
흔한 실수: PUT 을 부분 수정에 쓰는 것. 클라이언트가 일부만 보내면 나머지가 지워질 수 있어 사고가 납니다. 부분 수정이면 PATCH 를 쓰거나, PUT 을 쓰되 전체를 요구하는 것을 문서에 명시합니다.
Q.HTTP 멱등성이란 무엇이고 왜 중요한가요?
같은 요청을 여러 번 보내도 서버 상태가 한 번 보낸 것과 같은 성질입니다. 응답이 같다는 뜻은 아닙니다.
| 메서드 | 멱등 | 안전 |
|---|
| GET, HEAD | 예 | 예 |
| PUT | 예 | 아니오 |
| DELETE | 예 | 아니오 |
| POST | 아니오 | 아니오 |
| PATCH | 구현에 따라 | 아니오 |
DELETE 가 멱등인 이유는 두 번째 호출이 404 를 반환해도 상태는 여전히 삭제됨이기 때문입니다.
왜 중요한가는 재시도에서 드러납니다. 네트워크 타임아웃이 났을 때 처리됐는지 알 수 없는데, 멱등하면 그냥 다시 보내면 됩니다. 멱등하지 않으면 이중 결제가 됩니다.
그래서 POST 로 결제를 받을 때는 멱등키를 도입해 서버가 중복을 흡수하게 만듭니다.
흔한 실수: 멱등을 "응답이 같다"로 이해하는 것. 기준은 서버 상태입니다.
Q.RESTful API에서 메서드를 어떻게 사용하나요?
자원을 명사로 두고 동작은 메서드로 표현합니다.
| 동작 | 메서드와 경로 |
|---|
| 목록 조회 | GET /orders |
| 단건 조회 | GET /orders/123 |
| 생성 | POST /orders |
| 전체 수정 | PUT /orders/123 |
| 부분 수정 | PATCH /orders/123 |
| 삭제 | DELETE /orders/123 |
경로에 동사를 넣지 않는 것이 원칙입니다. POST /createOrder 대신 POST /orders 입니다.
다만 자원으로 표현하기 어려운 동작이 있습니다. 그때는 하위 자원이나 상태 변경으로 바꿉니다.
POST /orders/123/cancel 동작을 하위 자원으로
PATCH /orders/123 {"status":"cancelled"} 상태 변경으로
흔한 실수: 모든 것을 순수 REST 로 맞추려고 억지 경로를 만드는 것. 검색이나 일괄 처리처럼 자원 모델에 안 맞는 것은 실용적으로 표현하고 문서로 보완하는 편이 낫습니다.
먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.
읽었으면 문제로 확인해보세요
네트워크 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.