숏컷 코드
[
{ "op": "replace", "path": "/profile/name", "value": "Kim" },
{ "op": "add", "path": "/tags/-", "value": "new" },
{ "op": "remove", "path": "/draft" }
]관계
JSON Pointer는 위치 표기이고 JSON Patch는 변경 명령 목록이다
JSON Pointer는 JSON 문서 안의 특정 위치를 /profile/name처럼 가리키는 문자열 문법입니다. JSON Patch는 그 위치에 대해 add, remove, replace, move, copy, test 같은 작업을 순서대로 적용하는 patch document입니다. 즉 JSON Patch의 path 값이 JSON Pointer 문법을 사용합니다.
{
"profile": {
"name": "Lee"
}
}위 문서에서 /profile/name은 "Lee" 값을 가리킵니다. 여기에 replace 작업을 적용하면 전체 JSON을 다시 보내지 않고 해당 위치만 바꿀 수 있습니다.
/로 segment를 나누고 ~0, ~1만 특별하게 escape한다
JSON Pointer에서 /는 path segment 구분자입니다. object key 자체에 /나 ~가 들어 있으면 escape가 필요합니다. ~는 ~0, /는 ~1로 씁니다. 이 규칙을 URL percent encoding이나 파일 경로 escape와 섞으면 다른 위치를 가리키게 됩니다.
{
"a/b": {
"c~d": true
}
}위 값의 true를 가리키는 pointer는 /a~1b/c~0d입니다. /a/b/c~d라고 쓰면 a 아래 b 아래 c~d를 찾으려 하므로 완전히 다른 경로입니다.
배열 index는 숫자 segment로 가리킨다
배열 안의 값은 /items/0처럼 0-based index로 가리킵니다. JSON Patch에서 add 작업은 배열 index 위치에 값을 삽입할 수 있고, - segment를 사용하면 배열 끝에 append할 수 있습니다.
[
{ "op": "add", "path": "/items/0", "value": "first" },
{ "op": "add", "path": "/items/-", "value": "last" }
]배열 patch는 순서에 민감합니다. 앞쪽 요소를 먼저 삭제하면 뒤쪽 index가 바뀌므로, 여러 삭제를 한 번에 적용할 때는 뒤 index부터 지우거나 서버 patch 엔진의 적용 순서를 정확히 확인해야 합니다.
작업 종류
| op | 의미 |
|---|---|
add | object member 추가 또는 배열 삽입 |
remove | 지정 위치 값 제거 |
replace | 기존 값을 새 값으로 교체 |
move | 한 위치의 값을 다른 위치로 이동 |
copy | 한 위치의 값을 다른 위치로 복사 |
test | 현재 값이 기대값과 같은지 확인 |
replace와 remove는 대상 위치가 이미 존재해야 합니다. 없는 위치를 만들고 싶으면 add를 써야 하고, 중첩 object 자체가 없으면 그 부모 구조를 먼저 만들어야 합니다.
주의할 점
JSON Patch는 명령 목록을 순서대로 적용합니다. 앞 작업이 배열 index나 object 구조를 바꾸면 뒤 작업의 path가 처음 예상한 위치와 달라질 수 있습니다. 또한 replace는 없는 값을 생성하지 않으므로 create와 update를 같은 의미로 쓰면 실패합니다.
HTTP API에서 JSON Patch를 받을 때는 보통 Content-Type: application/json-patch+json을 사용합니다. 단순 partial object merge와 JSON Patch는 다른 계약입니다. { "name": "Kim" } 같은 merge payload를 받는 API에 JSON Patch 배열을 보내면 서버가 이해할 수 없습니다.
참고 링크
2 sources