GET·POST·PUT·PATCH·DELETE 차이: REST API를 주차관제 예제로 이해하기

GET·POST·PUT·PATCH·DELETE 차이: REST API를 주차관제 예제로 이해하기#

디스크립션: REST API에서 사용하는 GET·POST·PUT·PATCH·DELETE의 차이를 실제 주차관제 API 사례로 알아봅니다. 차량 조회, 입차·출차 등록, 차량 정보 수정과 삭제를 예로 들어 Resource, URL, Status Code, Idempotency, 중복 요청, Retry, Event ID와 안전한 API 설계 방법까지 정리합니다.

1장 같은 HTTP인데 왜 Method를 나눌까#

주차관제 Server에 다음과 같은 요청이 있다고 하겠습니다.

차량 정보를 조회한다.

입차 기록을 만든다.

차량 정보를 수정한다.

입차 기록의 상태만 변경한다.

등록된 차량을 삭제한다.

모두 HTTP를 사용하지만 의도는 다릅니다.

REST API에서는 이런 의도를 HTTP Method로 구분합니다.

GET
POST
PUT
PATCH
DELETE

가 대표적입니다.

가장 단순하게 정리하면:

GET
→ 조회

POST
→ 생성 또는 작업 요청

PUT
→ Resource 전체 교체

PATCH
→ Resource 일부 변경

DELETE
→ Resource 제거 요청

입니다.

하지만 실제 API에서는 Method 이름만 외우기보다 어떤 Resource를 어떤 상태로 바꾸려는 것인지 이해하는 것이 더 중요합니다.


2장 REST API는 Resource를 중심으로 생각한다#

REST API에서 중요한 개념 중 하나가 Resource입니다.

주차관제 시스템이라면 다음과 같은 Resource가 있을 수 있습니다.

vehicles
entries
exits
payments
gates
subscriptions

예:

/vehicles/123

은 특정 차량 Resource를 나타낼 수 있습니다.

/entries/98765

는 특정 입차 기록을 나타낼 수 있습니다.

HTTP Method는 이 Resource에 어떤 작업을 할 것인지 표현합니다.

GET    /vehicles/123
PATCH  /vehicles/123
DELETE /vehicles/123

같은 URL이라도 Method가 다르면 의미가 달라집니다.


3장 GET은 Resource를 조회한다#

차량 정보를 조회한다고 하겠습니다.

GET /vehicles/123 HTTP/1.1
Host: api.example-park.com

Server는 해당 차량 정보를 찾아 Response를 반환할 수 있습니다.

{
  "vehicleId": "123",
  "vehicleNumber": "12가3456",
  "status": "active"
}

GET은 일반적으로 Server Resource를 조회하는 용도로 사용합니다.

예:

GET /vehicles/123

GET /entries/98765

GET /gates/gate-01/status

입니다.


GET은 반복해도 상태를 바꾸지 않도록 설계하는 것이 기본이다#

같은 GET을 여러 번 호출한다고 하겠습니다.

GET /vehicles/123

GET /vehicles/123

GET /vehicles/123

일반적으로 조회 때문에 차량 Resource가 생성되거나 삭제되어서는 안 됩니다.

이런 성질을 HTTP에서는 Safe Method와 연결해서 이해할 수 있습니다.

다만 Server Log나 통계 Count처럼 부수적인 내부 상태가 변할 수는 있습니다.

핵심은 GET 자체가 Resource 변경을 요청하는 Method가 아니라는 것입니다.


4장 POST는 새로운 Resource나 업무 요청을 보낼 때 많이 사용한다#

차량이 입차했다고 하겠습니다.

새로운 입차 Event를 등록하기 위해:

POST /entries HTTP/1.1
Host: api.example-park.com
Content-Type: application/json

{
  "eventId": "cam-01-20260924-001",
  "vehicleNumber": "12가3456",
  "gateId": "gate-A",
  "timestamp": "2026-09-24T08:30:12+09:00"
}

처럼 보낼 수 있습니다.

Server가 새로운 입차 Resource를 만들면:

HTTP/1.1 201 Created
Location: /entries/98765

처럼 응답할 수 있습니다.

Body:

{
  "entryId": "98765",
  "status": "accepted"
}

를 함께 반환할 수도 있습니다.


POST는 중복 요청을 특히 조심해야 한다#

장비가 다음 Event를 전송했습니다.

eventId
cam-01-20260924-001

Server는 정상적으로 저장했습니다.

그런데 Response가 장비에 도착하지 않았습니다.

장비는 Timeout으로 판단하고 다시 전송합니다.

POST #1
→ Server 저장 성공
→ Response 손실

POST #2
→ 같은 Event 재전송

Server가 아무 검증 없이 다시 저장하면:

입차 기록 1

입차 기록 2

가 만들어질 수 있습니다.

주차 시스템에서는 이런 중복이 요금이나 출차 처리까지 영향을 줄 수 있습니다.


5장 Event ID와 Idempotency가 필요한 이유#

중복 전송에 대비하려면 Event마다 고유한 식별자를 사용할 수 있습니다.

예:

{
  "eventId": "cam-01-20260924-001"
}

Server는:

이 eventId를 이미 처리했는가?

를 확인합니다.

처음 Request:

존재하지 않음
↓
새 Event 생성

재전송:

이미 존재
↓
중복 생성하지 않음

으로 처리할 수 있습니다.

API 설계에 따라 HTTP Header의 Idempotency-Key 같은 별도 Key를 사용할 수도 있습니다.

중요한 것은 Timeout이 발생했다고 최초 POST가 실패했다고 단정하면 안 된다는 것입니다.


6장 PUT과 PATCH는 무엇이 다를까#

차량 정보를 수정한다고 하겠습니다.

기존 Resource:

{
  "vehicleNumber": "12가3456",
  "ownerName": "Kim",
  "status": "active",
  "subscriptionType": "monthly"
}

여기서 status 하나만 바꾸고 싶습니다.

PUT과 PATCH는 이 상황을 다르게 표현할 수 있습니다.


PUT은 Resource 전체 표현을 교체하는 의미로 많이 사용한다#

예:

PUT /vehicles/123 HTTP/1.1
Content-Type: application/json

{
  "vehicleNumber": "12가3456",
  "ownerName": "Kim",
  "status": "inactive",
  "subscriptionType": "monthly"
}

기존 Resource 전체 표현을 새로운 표현으로 바꾸는 방식입니다.

따라서 일부 Field를 빼고 보내면 API 설계에 따라 해당 Field가 초기화되거나 Validation Error가 발생할 수도 있습니다.

실제 동작은 API Specification을 반드시 확인해야 합니다.


PATCH는 일부 Field만 수정한다#

같은 상황에서:

PATCH /vehicles/123 HTTP/1.1
Content-Type: application/json

{
  "status": "inactive"
}

처럼 필요한 Field만 보낼 수 있습니다.

따라서 일부 속성만 변경하는 업무에서는 PATCH가 자연스러운 경우가 많습니다.


7장 PUT과 PATCH의 차이를 주차관제로 비교해보자#

차량 Resource가 다음과 같다고 하겠습니다.

{
  "vehicleNumber": "12가3456",
  "status": "active",
  "discountType": "none",
  "memo": "employee"
}

PUT#

차량 Resource 전체를
새로운 내용으로 교체

PATCH#

status만 변경

또는

discountType만 변경

처럼 이해하면 쉽습니다.

정리하면:

Method 일반적인 의미
PUT 전체 교체
PATCH 일부 변경

하지만 실제 API가 반드시 이 관습을 따르는 것은 아니므로 API 문서를 확인해야 합니다.


8장 출차 등록은 POST일까 PATCH일까#

출차는 REST API 설계에서 여러 방식으로 표현할 수 있습니다.

별도의 출차 Resource를 만드는 방식#

POST /exits

Body:

{
  "entryId": "98765",
  "exitGate": "gate-B",
  "timestamp": "2026-09-24T18:10:00+09:00"
}

출차 자체를 새로운 Event 또는 Resource로 보는 방식입니다.


기존 입차 Resource 상태를 변경하는 방식#

입차 기록:

/entries/98765

이 있고 이를:

PATCH /entries/98765

로 변경할 수도 있습니다.

예:

{
  "status": "exited",
  "exitTime": "2026-09-24T18:10:00+09:00"
}

둘 중 어느 것이 무조건 옳다고 할 수는 없습니다.

Domain Model에 따라 선택합니다.

출차를 독립 Event로 관리
→ POST /exits

입차 Session의 상태 변경
→ PATCH /entries/{id}

처럼 판단할 수 있습니다.


9장 DELETE는 실제 Database Row 삭제와 같은 뜻일까#

API에서:

DELETE /vehicles/123

을 호출했다고 하겠습니다.

이것이 반드시 Database에서:

DELETE FROM vehicles ...

를 실행한다는 뜻은 아닙니다.

Application에서는 다음처럼 처리할 수도 있습니다.

status = deleted

deletedAt = 현재 시각

이를 Logical Delete, 즉 논리 삭제라고 합니다.

반대로 실제 데이터를 제거하는 것은 Physical Delete라고 볼 수 있습니다.


주차관제에서는 삭제보다 비활성화가 필요한 경우가 많다#

차량 Resource를 제거하더라도 과거:

입차 기록

출차 기록

요금 기록

정기권 기록

감사 기록

을 유지해야 할 수 있습니다.

따라서:

DELETE

를 받더라도 실제 구현에서는:

inactive

deleted

revoked

상태로 변경하는 방법을 사용할 수 있습니다.

보관기간과 개인정보 처리 정책도 함께 고려해야 합니다.


10장 HTTP Method의 Idempotency를 이해하자#

Idempotent는 같은 요청을 여러 번 실행해도 최종 Resource 상태가 한 번 실행했을 때와 같다는 의미입니다.

일반적인 HTTP 의미를 기준으로 보면:

Method Idempotent 성질
GET Yes
PUT Yes
DELETE Yes
POST 기본적으로 보장하지 않음
PATCH 요청 내용에 따라 다를 수 있음

예를 들어:

PUT /vehicles/123

{
  "status": "inactive"
}

를 여러 번 실행해도 최종 상태는:

inactive

입니다.


DELETE도 Idempotent라고 하는 이유#

첫 번째:

DELETE
↓
Resource 삭제

두 번째:

DELETE
↓
이미 없음

이라도 최종 Resource 상태는:

없음

으로 동일합니다.

Response Status Code까지 반드시 같아야 한다는 의미는 아닙니다.


POST가 위험한 이유#

POST /payments

를 두 번 보내면 Payment가 두 건 생성될 수 있습니다.

따라서 Retry가 필요한 POST에는:

Request ID

Event ID

Idempotency Key

Transaction ID

같은 중복 방지 장치가 중요합니다.


11장 HTTP 성공과 업무 성공은 분리해서 본다#

입차 등록 API가:

HTTP/1.1 201 Created

를 반환했다고 하겠습니다.

이것은 입차 Resource가 정상적으로 생성됐다는 의미로 사용할 수 있습니다.

하지만 이후:

회원 조회

정기권 확인

Gate Open Command

차단기 Motor 작동

까지 모두 성공했다는 의미는 아닐 수 있습니다.

예를 들어:

POST /entries
↓
201 Created
↓
입차 저장 완료
↓
Gate Command Queue 등록
↓
장비 Offline
↓
Gate Open 실패

일 수 있습니다.

따라서 상태를:

received

stored

authorized

gate-commanded

completed

failed

처럼 분리하면 장애 분석이 쉬워집니다.


12장 Status Code는 Method와 함께 해석한다#

대표적인 조합을 보면 이해가 쉽습니다.

GET#

200 OK
→ 조회 성공

404 Not Found
→ Resource 없음

POST#

201 Created
→ Resource 생성

400 Bad Request
→ 요청 형식 오류

409 Conflict
→ 중복 또는 상태 충돌

PUT·PATCH#

200 OK
→ 수정 성공 + Response Body

204 No Content
→ 수정 성공 + 반환 Body 없음

404 Not Found
→ 대상 Resource 없음

DELETE#

204 No Content
→ 삭제 성공

404 Not Found
→ 대상 없음

다만 API 정책에 따라 다른 Code를 선택할 수 있습니다.

Status Code 하나만 보는 것이 아니라 API 계약과 Response Body를 함께 봐야 합니다.


13장 주차관제 REST API 전체 흐름을 만들어보자#

차량이 진입한다고 하겠습니다.

1. 차량 조회#

GET /vehicles/12가3456

Response:

200 OK

회원 차량이라고 판단합니다.


2. 입차 Event 생성#

POST /entries
{
  "eventId": "event-1001",
  "vehicleNumber": "12가3456",
  "gateId": "gate-A"
}

Server:

201 Created

3. Gate 상태 조회#

GET /gates/gate-A/status

Response:

{
  "state": "closed"
}

4. 출차 시 입차 Session 종료#

PATCH /entries/98765
{
  "status": "exited",
  "exitTime": "2026-09-24T18:10:00+09:00"
}

이렇게 HTTP Method가 실제 업무 흐름과 연결됩니다.


14장 중복 입차가 발생하면 무엇부터 확인할까#

현장 화면에 동일 차량의 입차 기록이 두 건 생겼다고 하겠습니다.

Log:

08:30:10 POST event-1001
08:30:12 POST event-1001

먼저 확인할 것은:

Client Retry가 있었는가?

첫 Response가 Timeout됐는가?

eventId가 동일한가?

Server 중복 검사가 있는가?

두 Request가 실제 다른 Sensor Event인가?

입니다.

단순히:

카메라가 두 번 인식했다.

고 단정하면 안 됩니다.

Network Retry로 같은 Event가 다시 전송되었을 수도 있습니다.


중복 진단에는 Trace ID가 유용하다#

예:

TRACE
req-a812

EVENT
event-1001

처럼 Request 식별자와 업무 Event 식별자를 분리하면 좋습니다.

동일 Event가:

Request A

Request B

로 두 번 전송되었는지 확인할 수 있기 때문입니다.

즉:

Trace ID
→ HTTP 요청 추적

Event ID
→ 업무 Event 추적

으로 역할을 나눌 수 있습니다.


15장 Retry 정책은 Method마다 다르게 봐야 한다#

Network Timeout이 발생했습니다.

GET#

상대적으로 재시도하기 쉽습니다.

GET 실패
↓
Retry

조회 자체가 Resource를 변경하지 않기 때문입니다.

POST#

주의해야 합니다.

POST
↓
Server 처리 성공
↓
Response 손실
↓
Client Retry

가 가능하기 때문입니다.

PUT#

동일 Resource를 동일 상태로 만드는 요청이라면 반복 실행에 비교적 안전하도록 설계할 수 있습니다.

PATCH#

PATCH는 내용에 따라 다릅니다.

예:

{
  "status": "inactive"
}

처럼 절대값으로 변경하는 것은 반복해도 최종 상태가 같을 수 있습니다.

하지만:

{
  "increment": 1
}

같은 의미라면 반복 실행 때 결과가 달라질 수 있습니다.

따라서 Method 이름만으로 Retry 안전성을 판단해서는 안 됩니다.


16장 API와 실제 장비 제어는 분리하는 편이 좋다#

예를 들어:

POST /gates/gate-A/open

이라는 API를 만들 수 있습니다.

하지만 Server가 HTTP Request를 받자마자:

Gate Relay ON

을 단순 실행하고 성공 처리하는 구조는 장애 대응이 어려울 수 있습니다.

조금 더 명확하게:

HTTP Command 접수
↓
권한 확인
↓
Command 생성
↓
Device 상태 확인
↓
장비 전송
↓
ACK
↓
Sensor 상태 확인
↓
완료 Event

로 분리할 수 있습니다.

특히 차단기와 같은 물리 장비에서는 API Response와 실제 물리 동작 완료를 분리해서 관리하는 것이 중요합니다.


17장 장애 상황에서는 Method보다 현재 상태를 먼저 확인한다#

출차 처리 API가 Timeout됐다고 하겠습니다.

바로 같은 POST를 다시 보내기보다:

해당 출차가 이미 등록됐는가?

Payment가 이미 승인됐는가?

입차 Session이 이미 종료됐는가?

를 확인하는 것이 안전할 수 있습니다.

예:

GET /entries/98765

Response:

{
  "status": "exited"
}

라면 최초 Request가 이미 처리됐을 가능성이 있습니다.

이처럼 Retry 전에 현재 Resource 상태를 조회하는 전략도 사용할 수 있습니다.


18장 개인정보와 인증을 함께 고려한다#

주차 API에는 다음과 같은 정보가 들어갈 수 있습니다.

차량번호

회원 ID

전화번호

결제 정보

입출차 시각

따라서 운영 API에서는:

HTTPS

Authentication

Authorization

접근 통제

Log Masking

보관기간

을 함께 설계해야 합니다.

예:

Authorization: Bearer ...

같은 인증 Header를 사용할 수 있습니다.

중요한 것은 Token 전체를 Application Log에 그대로 남기지 않는 것입니다.


19장 REST API 현장 판단표#

업무 Method 예 핵심 판단
차량 조회 GET 상태 변경 없이 조회
입차 생성 POST 중복 Event 방지 필요
출차 Event 생성 POST Transaction 중복 주의
입차 상태 변경 PATCH 일부 Field 변경
차량 전체 정보 교체 PUT 전체 표현 기준 확인
차량 일부 정보 수정 PATCH 변경 Field만 전달
차량 제거 DELETE 물리·논리 삭제 정책 확인
Gate 상태 조회 GET 실제 Sensor 상태 확인
Gate 동작 요청 POST 등 API 성공과 물리 완료 구분

20장 흔히 하는 잘못된 판단#

GET은 항상 Cache해도 된다#

아닙니다.

실시간 Gate 상태처럼 오래된 Cache가 위험한 Resource도 있습니다.

Cache 정책은 Resource 특성에 맞춰야 합니다.

POST는 한 번만 전달된다#

Network Retry로 여러 번 도착할 수 있습니다.

PUT은 무조건 일부 수정이다#

일반적인 REST 의미에서는 Resource 전체 교체에 사용합니다.

PATCH는 항상 Idempotent하다#

Patch 내용에 따라 반복 실행 결과가 달라질 수 있습니다.

DELETE는 Database Record를 실제로 지운다#

Logical Delete로 구현할 수도 있습니다.

HTTP 201이면 차단기가 열렸다#

Resource 생성 성공과 실제 물리 장비 동작은 별개의 상태일 수 있습니다.

409가 나오면 Network 문제다#

Resource 충돌이나 중복 요청 같은 Application 상태 문제일 가능성이 있습니다.


21장 REST API 설계 체크리스트#

□ Resource 이름이 명확한가?

□ URL에 동사보다 Resource 중심 표현을 사용하고 있는가?

□ 조회에는 GET을 사용하고 있는가?

□ 새 Resource 생성에는 POST가 적절한가?

□ 전체 교체와 일부 수정이 구분되어 있는가?

□ DELETE의 실제 정책이 문서화되어 있는가?

□ POST 중복 처리를 고려했는가?

□ Event ID가 있는가?

□ Request ID 또는 Trace ID가 있는가?

□ Retry 가능한 요청과 위험한 요청을 구분했는가?

□ Timeout 후 현재 상태를 조회할 방법이 있는가?

□ 200·201·204를 적절히 구분하는가?

□ 400·401·403·404·409를 구분하는가?

□ API 성공과 업무 완료 상태를 분리했는가?

□ HTTPS를 사용하고 있는가?

□ 인증과 권한 검사를 하고 있는가?

□ 개인정보를 Log에 그대로 남기지 않는가?

22장 자기 점검#

차량 정보를 조회할 때 적합한 Method는 무엇인가#

일반적으로 GET을 사용합니다.

입차 Event를 생성할 때 POST를 사용하면 무엇을 조심해야 하는가#

Timeout과 Retry 때문에 같은 Event가 여러 번 전달될 수 있으므로 Event ID나 Idempotency 정책을 적용해야 합니다.

PUT과 PATCH의 가장 큰 차이는 무엇인가#

일반적으로 PUT은 Resource 전체 표현을 교체하는 용도이고 PATCH는 일부 Field를 변경하는 용도로 사용합니다.

DELETE는 반드시 데이터를 실제 삭제하는가#

아닙니다. 업무·감사·보관 정책에 따라 Logical Delete로 구현할 수도 있습니다.

HTTP 요청이 성공했으면 실제 Gate 동작도 성공한 것인가#

반드시 그렇지 않습니다. HTTP 처리 결과와 실제 장비의 물리적 상태는 별도로 확인해야 합니다.

23장 이 글을 마치며#

HTTP Method는 단순히:

GET

POST

PUT

PATCH

DELETE

다섯 단어를 외우는 것이 아닙니다.

각 Method에는 Resource를 어떻게 다룰 것인지에 대한 의도가 담겨 있습니다.

GET
→ 조회

POST
→ 생성 또는 업무 요청

PUT
→ 전체 교체

PATCH
→ 일부 변경

DELETE
→ 제거 요청

그리고 실제 산업 시스템에서는 여기에 더 많은 조건이 붙습니다.

HTTP Method
↓
Request
↓
Status Code
↓
Resource 상태
↓
Database 처리
↓
장비 Command
↓
실제 물리 상태

이 단계들은 서로 같은 성공 상태가 아닙니다.

특히 다음 다섯 가지를 기억하면 됩니다.

GET·POST·PUT·PATCH·DELETE는 단순한 명령어가 아니라 Resource에 어떤 의도를 적용하는지를 표현합니다.

POST 기반 Event 등록은 Network Timeout과 Retry 때문에 중복될 수 있으므로 Event ID나 Idempotency 정책이 중요합니다.

PUT과 PATCH는 전체 교체와 부분 변경이라는 차이를 이해하고 API 계약에 맞춰 사용해야 합니다.

HTTP Status Code가 성공이어도 이후 Database·Queue·장비 동작까지 모두 완료됐다는 뜻은 아닐 수 있습니다.

주차관제처럼 실제 물리 장비가 연결된 시스템에서는 API 요청 성공과 최종 Sensor 상태를 분리해 추적해야 합니다.

결국 REST API를 제대로 설계한다는 것은 어떤 상황에 GET이나 POST를 붙일지 외우는 것이 아닙니다.

Resource의 현재 상태와 변경 의도를 명확히 표현하고, 지연·중복·실패가 발생해도 같은 업무가 안전하고 추적 가능하게 처리되도록 API 계약을 만드는 것이 핵심입니다.

이 페이지의 목차