JSON 패치: API 데이터 효율적 업데이트 방법

INEZA Felin-Michel

INEZA Felin-Michel

1 September 2025

JSON 패치: API 데이터 효율적 업데이트 방법

현대적인 API를 구축하셨습니다. GET은 데이터를 가져오고, POST는 새로운 리소스를 생성합니다—여기까지는 순조롭습니다. 하지만 데이터를 업데이트하는 데 있어서는 상황이 복잡해집니다.

사용자가 이메일만 변경하고 싶다고 가정해 봅시다. 사용자 프로필 전체를 다시 보내도록 해야 할까요? 이는 번거롭고, 비효율적이며, 오류가 발생하기 쉽습니다—특히 연결 속도가 느리거나 업데이트가 충돌할 때 더욱 그렇습니다.

더 나은 방법이 있습니다: JSON Patch.
전체 객체를 보내는 대신, 변경 사항만 보냅니다. 마치 양복 전체를 다시 만드는 대신 재단사에게 수선 목록을 주는 것과 같다고 생각해보세요.

JSON이 API의 보편적인 언어가 되면서, JSON Patch는 부분 업데이트를 위한 가볍고 우아한 솔루션을 제공합니다.

물론, JSON Patch를 사용하여 API를 설계하고 테스트하려면 올바른 도구가 필요합니다. 바로 Apidog가 필요한 이유입니다. Apidog를 사용하면 JSON Patch 요청을 쉽게 만들고, 테스트하고, 유효성을 검사할 수 있습니다—따라서 단 한 줄의 코드를 작성하기 전에 업데이트가 의도한 대로 작동하는지 알 수 있습니다. 무엇보다도, 오늘 무료로 다운로드하여 실험을 시작할 수 있습니다.

💡
아름다운 API 문서를 생성하는 훌륭한 API 테스트 도구를 원하십니까?

개발팀이 최대한의 생산성으로 함께 작업할 수 있는 통합된 올인원 플랫폼을 원하십니까?

Apidog는 모든 요구 사항을 충족하며, 훨씬 더 저렴한 가격으로 Postman을 대체합니다!
button

다음으로, 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%가 변경되지 않았음에도 불구하고 모든 필드를 다시 보내야 했습니다. 이 접근 방식에는 몇 가지 단점이 있습니다:

  1. 대역폭 증가: 불필요한 데이터를 많이 전송하고 있습니다. 대규모 리소스의 경우, 특히 모바일 네트워크에서 상당한 성능 저하를 초래할 수 있습니다.
  2. 충돌 위험 증가: John이 email을 편집하는 동안 다른 프로세스가 age 필드를 업데이트하면, John의 PUT 요청이 실수로 그가 보낸 이전 값으로 새로운 나이를 덮어쓸 수 있습니다.
  3. 클라이언트 복잡성: 클라이언트 애플리케이션은 먼저 전체 리소스를 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 문서 내에서 조작하려는 특정 값으로 이동하기 위해 슬래시 기반 구문을 사용하는 문자열입니다.

이 구문은 중첩된 JSON 구조를 탐색하는 데 강력합니다.

JSON Patch vs JSON Merge Patch

개발자들은 종종 JSON Patch (RFC 6902)와 JSON Merge Patch (RFC 7386)를 혼동합니다. 명확히 해봅시다.

JSON Patch:

JSON Merge 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 작업은 본질적으로 동일한 경로에서 removeadd의 조합입니다. 이는 특정 위치의 기존 값을 새 값으로 대체합니다. 우리의 이메일 예시는 전형적인 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를 사용하는 이유? 장점

  1. 효율성: 가장 분명한 이점입니다. 변경 사항만 전송하여 페이로드 크기를 크게 줄이고 성능을 향상시킵니다.
  2. 동시성 제어: test 작업은 낙관적 잠금을 위한 내장 메커니즘을 제공하여, 손실된 업데이트와 경쟁 조건을 피하는 데 도움이 됩니다.
  3. 원자성: 패치 적용의 전체 또는 전무(all-or-nothing) 특성은 데이터의 일관성을 보장합니다. 10개 작업 중 5번째 작업이 실패하면, 처음 4개 작업은 롤백됩니다.
  4. 명확성과 의도: 요청 본문은 단순히 새로운 상태를 덤핑하는 대신 변경의 의도("이메일 교체", "취미 추가")를 명확하게 설명합니다. 이는 로그를 더 읽기 쉽게 만들고 디버깅을 더 쉽게 만듭니다.
  5. 표준화: 이는 IETF 표준(RFC 6902)입니다. 다른 개발자들도 이를 인식할 것이며, 다양한 프로그래밍 언어의 많은 라이브러리와 프레임워크에는 JSON Patch 문서를 파싱하고 적용하기 위한 내장 지원이 있습니다.

JSON Patch의 일반적인 함정과 실수

JSON Patch는 강력하지만, 개발자들은 종종 다음과 같은 문제에 부딪힙니다:

API가 JSON Patch를 사용하는 이유

API는 JSON Patch를 선호합니다. 그 이유는 다음과 같습니다:

예를 들어, GitHub의 API는 저장소 메타데이터를 효율적으로 편집하기 위해 JSON Patch를 지원합니다.

REST API의 JSON Patch

RESTful API에서 JSON Patch는 종종 HTTP PATCH 메서드와 함께 사용됩니다.

PATCH vs PUT:

JSON Patch에서 Content-Type은 다음과 같습니다:

application/json-patch+json

이는 서버에게 본문에 JSON Patch 문서가 포함되어 있음을 알려줍니다.

GraphQL 및 기타 프로토콜의 JSON Patch

JSON Patch는 주로 REST API에서 사용되지만, 다음 분야에서도 관련성이 있습니다:

JSON Patch가 효율성을 향상시키는 방법

사용자 프로필을 동기화하는 모바일 앱을 상상해 보세요. 작은 업데이트마다 2MB JSON 파일을 다시 업로드하는 대신, 앱은 작은 패치 요청만 보낼 수 있습니다.

이는 다음을 의미합니다:

도전 과제 및 고려 사항

JSON Patch는 강력하지만, 복잡성이 없는 것은 아닙니다.

  1. 서버에서의 복잡한 구현: 서버에서 패치를 올바르게 적용하는 것은 단순히 새로운 JSON 객체를 받아들이는 것보다 더 복잡합니다. 각 작업을 유효성 검사하고, 존재하지 않는 경로에 대한 포인터를 적절하게 처리하며, 전체 시퀀스가 원자적으로 적용되도록 해야 합니다. 다행히도 대부분의 최신 웹 프레임워크에는 이를 처리하는 라이브러리가 있습니다 (예: Node.js용 json-patch, Python용 jsonpatch, .NET의 JsonPatchDocument).
  2. 오류 발생 가능성: 잘못 구성된 패치 문서 또는 유효하지 않은 포인터(예: 존재하지 않는 필드를 replace하려는 시도)는 오류를 발생시킵니다. API는 이러한 오류를 우아하게 처리하고 명확한 오류 메시지를 반환해야 합니다 (일반적으로 422 Unprocessable Entity 또는 400 Bad Request).
  3. 만능 해결책 아님: 매우 간단한 리소스의 경우, PUT이 여전히 더 간단할 수 있습니다. JSON Patch는 리소스가 크거나 복잡하고 조건부 업데이트를 지원해야 할 때 빛을 발합니다.

Apidog로 JSON Patch 엔드포인트 테스트하기

JSON Patch를 수동으로 테스트하는 것은 답답할 수 있습니다. 이때 정교한 API 도구가 매우 유용해집니다. 올인원 API 개발 플랫폼인 Apidog는 이 경우 큰 도움이 될 수 있습니다:

button

Apidog에서의 예시 워크플로우:

  1. 새 요청을 생성합니다.
  2. 메서드를 PATCH로 설정합니다.
  3. Content-Type: application/json-patch+json을 추가합니다.
  4. JSON Patch 배열을 입력합니다.
  5. 즉시 전송하고 결과를 확인합니다.

Apidog를 사용하면 패치가 올바른지 추측하는 단계에서 올바르게 구축되었음을 아는 단계로 나아가, JSON Patch API를 자신 있게 구현하고 사용하며 전문가처럼 JSON Patch 테스트를 시작할 수 있습니다.

JSON Patch 모범 사례

JSON Patch를 효과적으로 사용하려면:

  1. 전송하기 전에 JSON Patch 문서를 유효성 검사하세요.
  2. 일관성이 중요할 때 테스트 작업을 사용하세요.
  3. 효율성을 위해 패치를 작게 유지하세요.
  4. JSON Patch를 사용할 때 API를 명확하게 문서화하세요.
  5. 테스트를 간소화하기 위해 Apidog와 같은 도구를 사용하세요.

결론: 더 효율적인 API 표준 수용

그렇다면 JSON Patch란 무엇일까요?

이는 추가(add), 제거(remove), 교체(replace)와 같은 작업을 사용하여 JSON 문서에 대한 변경 사항을 설명하는 표준화된 방법입니다. 전체 객체를 보내는 대신 변경 사항만 보낼 수 있어 API를 더욱 효율적이고, 신뢰할 수 있으며, 유연하게 만듭니다.

JSON Patch는 API를 통한 데이터 업데이트 방식에 대한 우리의 생각을 변화시킵니다. 이는 전체 문서 교체라는 무딘 도구에서 정교한 수술적 변경으로 우리를 이끌어줍니다. 이 표준을 수용함으로써 우리는 더 효율적이고, 충돌에 덜 취약하며, 의도가 더 명확한 API를 구축할 수 있습니다.

서버 측에서 약간 더 많은 사전 고려가 필요하지만, 클라이언트 애플리케이션 및 네트워크 성능에 대한 이점은 상당합니다. 다음번에 업데이트 엔드포인트를 설계할 때, 기본 PUT을 고집하지 말고 스스로에게 물어보세요: "이것은 PATCH의 역할일 수 있을까?"

개발자에게 JSON Patch를 이해하는 것은 특히 부분 업데이트를 처리할 때 현대 API와 작업하는 데 핵심입니다. 그리고 Apidog와 같은 도구를 사용하면 JSON Patch 요청을 쉽게 테스트하고, 유효성을 검사하고, 디버그할 수 있습니다.

button

Apidog에서 API 설계-첫 번째 연습

API를 더 쉽게 구축하고 사용하는 방법을 발견하세요