현대적인 API를 구축하셨습니다. GET은 데이터를 가져오고, POST는 새로운 리소스를 생성합니다—여기까지는 순조롭습니다. 하지만 데이터를 업데이트하는 데 있어서는 상황이 복잡해집니다.
사용자가 이메일만 변경하고 싶다고 가정해 봅시다. 사용자 프로필 전체를 다시 보내도록 해야 할까요? 이는 번거롭고, 비효율적이며, 오류가 발생하기 쉽습니다—특히 연결 속도가 느리거나 업데이트가 충돌할 때 더욱 그렇습니다.
더 나은 방법이 있습니다: JSON Patch.
전체 객체를 보내는 대신, 변경 사항만 보냅니다. 마치 양복 전체를 다시 만드는 대신 재단사에게 수선 목록을 주는 것과 같다고 생각해보세요.
JSON이 API의 보편적인 언어가 되면서, JSON Patch는 부분 업데이트를 위한 가볍고 우아한 솔루션을 제공합니다.
물론, JSON Patch를 사용하여 API를 설계하고 테스트하려면 올바른 도구가 필요합니다. 바로 Apidog가 필요한 이유입니다. Apidog를 사용하면 JSON Patch 요청을 쉽게 만들고, 테스트하고, 유효성을 검사할 수 있습니다—따라서 단 한 줄의 코드를 작성하기 전에 업데이트가 의도한 대로 작동하는지 알 수 있습니다. 무엇보다도, 오늘 무료로 다운로드하여 실험을 시작할 수 있습니다.
개발팀이 최대한의 생산성으로 함께 작업할 수 있는 통합된 올인원 플랫폼을 원하십니까?
Apidog는 모든 요구 사항을 충족하며, 훨씬 더 저렴한 가격으로 Postman을 대체합니다!
다음으로, JSON Patch가 무엇인지, 어떻게 작동하는지, 그리고 왜 다음 프로젝트에 포함되어야 하는지 자세히 알아보겠습니다.
문제: "맹목적인" PUT 요청

JSON Patch가 왜 그렇게 유용한지 이해하려면, 먼저 JSON Patch가 해결하는 문제를 이해해야 합니다. 전통적으로 RESTful API에서 리소스를 업데이트하는 것은 PUT
HTTP 메서드를 통해 이루어집니다.
PUT
요청은 멱등성(동일한 요청을 여러 번 해도 한 번 한 것과 같은 효과를 가짐)을 갖도록 의도되었으며, 일반적으로 대상 URL의 전체 리소스를 요청 본문에 제공된 새로운 표현으로 대체합니다.
사용자 프로필 리소스를 상상해 봅시다:
GET /users/123
{
"id": 123,
"username": "johndoe",
"email": "john.old@example.com",
"firstName": "John",
"lastName": "Doe",
"age": 30,
"accountStatus": "active",
"preferences": {
"theme": "light",
"notifications": true
},
"signUpDate": "2023-01-15"
}
이제 John이 이메일 주소만 변경하고 싶다면, 일반적인 PUT
요청은 다음과 같을 것입니다:
PUT /users/123
{
"id": 123,
"username": "johndoe",
"email": "john.new@example.com", // The changed field
"firstName": "John",
"lastName": "Doe",
"age": 30,
"accountStatus": "active",
"preferences": {
"theme": "light",
"notifications": true
},
"signUpDate": "2023-01-15"
}
문제가 보이시나요? 데이터의 99%가 변경되지 않았음에도 불구하고 모든 필드를 다시 보내야 했습니다. 이 접근 방식에는 몇 가지 단점이 있습니다:
- 대역폭 증가: 불필요한 데이터를 많이 전송하고 있습니다. 대규모 리소스의 경우, 특히 모바일 네트워크에서 상당한 성능 저하를 초래할 수 있습니다.
- 충돌 위험 증가: John이
email
을 편집하는 동안 다른 프로세스가age
필드를 업데이트하면, John의PUT
요청이 실수로 그가 보낸 이전 값으로 새로운 나이를 덮어쓸 수 있습니다. - 클라이언트 복잡성: 클라이언트 애플리케이션은 먼저 전체 리소스를
GET
하고, 특정 필드를 수정한 다음, 전체를 다시PUT
해야 합니다. 이는 여러 단계가 필요하며 클라이언트가 전체 상태를 관리해야 합니다.
이것이 바로 HTTP PATCH
메서드가 필요한 이유입니다.
해결책: HTTP PATCH 및 JSON Patch 소개
HTTP PATCH
메서드는 리소스의 부분적인 수정을 허용하기 위해 도입되었습니다. 전체 리소스를 대체하는 PUT
과 달리, PATCH
는 리소스에 일련의 변경 사항을 적용합니다.
하지만 한 가지 문제가 있습니다: HTTP 표준은 이러한 "변경 사항"의 형식이 무엇이어야 하는지 정의하지 않습니다. 자신만의 형식을 만들 수도 있습니다. 다음과 같은 것을 보낼 수도 있습니다:
{ "op": "change_email", "value": "new@example.com" }
하지만 이는 사용자 지정이며 비표준적이며, 다른 개발자들이 당신의 특정 언어를 배워야 할 것입니다.
이것이 바로 JSON Patch가 채우는 간극입니다. JSON Patch (RFC 6902에 정의됨)는 JSON 문서에 적용될 변경 사항을 지정하기 위한 표준화된 형식입니다. 이는 JSON 문서가 정확히 어떻게 수정되어야 하는지를 설명하는 명확하고 모호하지 않은 언어를 제공합니다.
HTTP PATCH
메서드를 JSON Patch 문서 형식의 본문과 결합하면, 부분 업데이트를 수행하는 강력하고 표준 기반의 방법을 갖게 됩니다.
JSON Patch 작동 방식: 기본
JSON Patch 문서는 항상 JSON 배열입니다. 배열의 각 요소는 작업 객체입니다. 이 작업들은 대상 문서에 순서대로 적용되며, 전체 패치는 원자적입니다. 즉, 단일 작업이라도 실패하면 전체 패치가 중단되고 문서는 변경되지 않은 상태로 유지됩니다.
모든 작업 객체에는 수행할 작업을 지정하는 필수 op
멤버("operation"의 약어)가 있습니다. 가장 일반적인 작업은 add
, remove
, replace
, move
, 그리고 copy
입니다.
John이 이메일을 변경하는 이전 예시를 살펴보겠습니다. JSON Patch를 사용하면 요청이 훨씬 더 간단해집니다:
PATCH /users/123
[
{ "op": "replace", "path": "/email", "value": "john.new@example.com" }
]
그게 다입니다! 우리는 단일 작업을 보내고 있습니다: "'/email' 경로의 값을 이 새로운 값으로 교체하세요." 요청은 작고, 명확하며, 의도 중심적입니다. 다른 필드는 전혀 건드리지 않습니다.
path
속성 이해하기
path
속성은 JSON Pointer(RFC 6901)이며, JSON 문서 내에서 조작하려는 특정 값으로 이동하기 위해 슬래시 기반 구문을 사용하는 문자열입니다.
"/email"
은 루트 레벨email
필드를 가리킵니다."/preferences/theme"
은preferences
객체 내부의theme
필드를 가리킵니다."/firstName"
은firstName
필드를 가리킵니다.
이 구문은 중첩된 JSON 구조를 탐색하는 데 강력합니다.
JSON Patch vs JSON Merge Patch
개발자들은 종종 JSON Patch (RFC 6902)와 JSON Merge Patch (RFC 7386)를 혼동합니다. 명확히 해봅시다.
JSON Patch:
- 일련의 작업을 설명합니다.
- 매우 정밀하며 복잡한 업데이트를 허용합니다.
- 예시: 교체(replace), 이동(move), 복사(copy).
JSON Merge Patch:
- 원본에 병합될 부분 JSON 문서를 보냅니다.
- 더 간단하지만 유연성이 떨어집니다.
- 예시:
{ "name": "Bob" }
은 name 필드를 대체합니다.
요약하자면:
- 간단하고 얕은 업데이트에는 JSON Merge Patch를 사용하세요.
- 복잡하거나 여러 작업에는 JSON Patch를 사용하세요.
JSON Patch 작업
가장 일반적인 작업들을 예시와 함께 살펴보겠습니다. 동일한 사용자 프로필을 대상 문서로 사용하겠습니다.
1. add
작업
add
작업은 객체나 배열에 새 값을 삽입하는 데 사용됩니다.
객체에 새 속성 추가:
{ "op": "add", "path": "/twitterHandle", "value": "@johndoe" }
이는 사용자 객체에 새로운 twitterHandle
필드를 추가합니다.
배열에 요소 추가 (특정 인덱스에):
사용자가 "hobbies"
배열: ["reading", "cycling"]
을 가지고 있다고 상상해 보세요.
{ "op": "add", "path": "/hobbies/1", "value": "hiking" }
이것은 인덱스 1에 "hiking"을 삽입하여 ["reading", "hiking", "cycling"]
이 됩니다. 배열의 끝에 추가하려면 /-
를 사용할 수 있습니다: { "op": "add", "path": "/hobbies/-", "value": "hiking" }
.
2. remove
작업
remove
작업은 지정된 위치의 값을 삭제합니다.
객체에서 속성 제거:
{ "op": "remove", "path": "/age" }
이는 사용자 객체에서 전체 age
필드를 제거합니다.
배열에서 요소 제거:
{ "op": "remove", "path": "/hobbies/0" }
이는 hobbies
배열에서 첫 번째 요소(인덱스 0)를 제거합니다.
3. replace
작업
replace
작업은 본질적으로 동일한 경로에서 remove
와 add
의 조합입니다. 이는 특정 위치의 기존 값을 새 값으로 대체합니다. 우리의 이메일 예시는 전형적인 replace
였습니다.
사용자의 테마 환경설정 변경:
{ "op": "replace", "path": "/preferences/theme", "value": "dark" }
4. move
작업
move
작업은 한 위치에서 값을 제거하고 다른 위치에 추가합니다.
한 속성에서 다른 속성으로 값 이동:
{ "op": "move", "from": "/firstName", "path": "/first_name" }
이는 firstName
의 값을 first_name
이라는 새 속성으로 이동시키고 이전 firstName
속성을 제거합니다.
5. copy
작업
copy
작업은 한 위치에서 다른 위치로 값을 복사합니다. 원본 값은 변경되지 않습니다.
설정 백업 생성:
{ "op": "copy", "from": "/preferences/theme", "path": "/backupTheme" }
이는 현재 테마 값을 새로운 backupTheme
필드로 복사합니다.
6. test
작업
이것은 안전 기능입니다. test
작업은 특정 위치의 값이 지정된 값과 같은지 확인합니다. 테스트가 실패하면 전체 패치가 중단됩니다. 이는 충돌을 방지하는 데(낙관적 잠금) 매우 유용합니다.
업데이트하기 전에 다른 사람이 이메일을 변경하지 않았는지 확인:
[
{ "op": "test", "path": "/email", "value": "john.old@example.com" },
{ "op": "replace", "path": "/email", "value": "john.new@example.com" }
]
만약 현재 email
이 "john.old@example.com"
이 아니라면 (아마도 다른 프로세스가 이미 변경했을 수 있음), test
작업은 실패하고 replace
는 결코 발생하지 않습니다. 이는 업데이트가 최신 알려진 상태를 기반으로 하는지 확인합니다.
JSON Patch를 사용하는 이유? 장점
- 효율성: 가장 분명한 이점입니다. 변경 사항만 전송하여 페이로드 크기를 크게 줄이고 성능을 향상시킵니다.
- 동시성 제어:
test
작업은 낙관적 잠금을 위한 내장 메커니즘을 제공하여, 손실된 업데이트와 경쟁 조건을 피하는 데 도움이 됩니다. - 원자성: 패치 적용의 전체 또는 전무(all-or-nothing) 특성은 데이터의 일관성을 보장합니다. 10개 작업 중 5번째 작업이 실패하면, 처음 4개 작업은 롤백됩니다.
- 명확성과 의도: 요청 본문은 단순히 새로운 상태를 덤핑하는 대신 변경의 의도("이메일 교체", "취미 추가")를 명확하게 설명합니다. 이는 로그를 더 읽기 쉽게 만들고 디버깅을 더 쉽게 만듭니다.
- 표준화: 이는 IETF 표준(RFC 6902)입니다. 다른 개발자들도 이를 인식할 것이며, 다양한 프로그래밍 언어의 많은 라이브러리와 프레임워크에는 JSON Patch 문서를 파싱하고 적용하기 위한 내장 지원이 있습니다.
JSON Patch의 일반적인 함정과 실수
JSON Patch는 강력하지만, 개발자들은 종종 다음과 같은 문제에 부딪힙니다:
- 잘못된 경로 사용 (JSON Pointer 구문 오류).
value
또는from
과 같은 필수 필드 누락.- 존재하지 않는 경로에 패치 적용.
test
작업을 잘못 과도하게 사용.- JSON Patch와 JSON Merge Patch 혼동.
API가 JSON Patch를 사용하는 이유
API는 JSON Patch를 선호합니다. 그 이유는 다음과 같습니다:
- 효율적: 변경된 내용만 보냅니다.
- 원자적: 하나의 요청으로 여러 변경 사항을 처리합니다.
- 유연함: 이동/복사와 같은 고급 작업을 지원합니다.
- 표준화됨: 다양한 시스템에서 작동합니다.
예를 들어, GitHub의 API는 저장소 메타데이터를 효율적으로 편집하기 위해 JSON Patch를 지원합니다.
REST API의 JSON Patch
RESTful API에서 JSON Patch는 종종 HTTP PATCH 메서드와 함께 사용됩니다.
PATCH vs PUT:
- PUT은 전체 리소스를 대체합니다.
- PATCH는 리소스의 일부를 업데이트합니다.
JSON Patch에서 Content-Type
은 다음과 같습니다:
application/json-patch+json
이는 서버에게 본문에 JSON Patch 문서가 포함되어 있음을 알려줍니다.
GraphQL 및 기타 프로토콜의 JSON Patch
JSON Patch는 주로 REST API에서 사용되지만, 다음 분야에서도 관련성이 있습니다:
- GraphQL 뮤테이션: 점진적 업데이트 적용.
- JSON 페이로드를 사용하는 gRPC: 구조화된 패치 전송.
- 이벤트 기반 아키텍처: 전체 객체 대신 변경 사항만 브로드캐스팅.
JSON Patch가 효율성을 향상시키는 방법
사용자 프로필을 동기화하는 모바일 앱을 상상해 보세요. 작은 업데이트마다 2MB JSON 파일을 다시 업로드하는 대신, 앱은 작은 패치 요청만 보낼 수 있습니다.
이는 다음을 의미합니다:
- 더 빠른 동기화 시간.
- 더 낮은 모바일 데이터 사용량.
- 더 나은 서버 성능.
도전 과제 및 고려 사항
JSON Patch는 강력하지만, 복잡성이 없는 것은 아닙니다.
- 서버에서의 복잡한 구현: 서버에서 패치를 올바르게 적용하는 것은 단순히 새로운 JSON 객체를 받아들이는 것보다 더 복잡합니다. 각 작업을 유효성 검사하고, 존재하지 않는 경로에 대한 포인터를 적절하게 처리하며, 전체 시퀀스가 원자적으로 적용되도록 해야 합니다. 다행히도 대부분의 최신 웹 프레임워크에는 이를 처리하는 라이브러리가 있습니다 (예: Node.js용
json-patch
, Python용jsonpatch
, .NET의JsonPatchDocument
). - 오류 발생 가능성: 잘못 구성된 패치 문서 또는 유효하지 않은 포인터(예: 존재하지 않는 필드를
replace
하려는 시도)는 오류를 발생시킵니다. API는 이러한 오류를 우아하게 처리하고 명확한 오류 메시지를 반환해야 합니다 (일반적으로422 Unprocessable Entity
또는400 Bad Request
). - 만능 해결책 아님: 매우 간단한 리소스의 경우,
PUT
이 여전히 더 간단할 수 있습니다. JSON Patch는 리소스가 크거나 복잡하고 조건부 업데이트를 지원해야 할 때 빛을 발합니다.
Apidog로 JSON Patch 엔드포인트 테스트하기

JSON Patch를 수동으로 테스트하는 것은 답답할 수 있습니다. 이때 정교한 API 도구가 매우 유용해집니다. 올인원 API 개발 플랫폼인 Apidog는 이 경우 큰 도움이 될 수 있습니다:
- 테스트: 시각화된 대시보드에서 PATCH 엔드포인트를 쉽게 테스트하고 응답 유효성 검사 결과를 얻을 수 있습니다.
- 문서화: Apidog 내에서 PATCH 엔드포인트를 문서화하여 다른 팀원들에게 예상 형식을 명확하게 보여줄 수 있으며, 이는 협업을 개선하고 통합 버그를 줄입니다.
Apidog에서의 예시 워크플로우:
- 새 요청을 생성합니다.
- 메서드를 PATCH로 설정합니다.
Content-Type: application/json-patch+json
을 추가합니다.- JSON Patch 배열을 입력합니다.
- 즉시 전송하고 결과를 확인합니다.
Apidog를 사용하면 패치가 올바른지 추측하는 단계에서 올바르게 구축되었음을 아는 단계로 나아가, JSON Patch API를 자신 있게 구현하고 사용하며 전문가처럼 JSON Patch 테스트를 시작할 수 있습니다.
JSON Patch 모범 사례
JSON Patch를 효과적으로 사용하려면:
- 전송하기 전에 JSON Patch 문서를 유효성 검사하세요.
- 일관성이 중요할 때 테스트 작업을 사용하세요.
- 효율성을 위해 패치를 작게 유지하세요.
- JSON Patch를 사용할 때 API를 명확하게 문서화하세요.
- 테스트를 간소화하기 위해 Apidog와 같은 도구를 사용하세요.
결론: 더 효율적인 API 표준 수용
그렇다면 JSON Patch란 무엇일까요?
이는 추가(add), 제거(remove), 교체(replace)와 같은 작업을 사용하여 JSON 문서에 대한 변경 사항을 설명하는 표준화된 방법입니다. 전체 객체를 보내는 대신 변경 사항만 보낼 수 있어 API를 더욱 효율적이고, 신뢰할 수 있으며, 유연하게 만듭니다.
JSON Patch는 API를 통한 데이터 업데이트 방식에 대한 우리의 생각을 변화시킵니다. 이는 전체 문서 교체라는 무딘 도구에서 정교한 수술적 변경으로 우리를 이끌어줍니다. 이 표준을 수용함으로써 우리는 더 효율적이고, 충돌에 덜 취약하며, 의도가 더 명확한 API를 구축할 수 있습니다.
서버 측에서 약간 더 많은 사전 고려가 필요하지만, 클라이언트 애플리케이션 및 네트워크 성능에 대한 이점은 상당합니다. 다음번에 업데이트 엔드포인트를 설계할 때, 기본 PUT
을 고집하지 말고 스스로에게 물어보세요: "이것은 PATCH
의 역할일 수 있을까?"
개발자에게 JSON Patch를 이해하는 것은 특히 부분 업데이트를 처리할 때 현대 API와 작업하는 데 핵심입니다. 그리고 Apidog와 같은 도구를 사용하면 JSON Patch 요청을 쉽게 테스트하고, 유효성을 검사하고, 디버그할 수 있습니다.