JSONPath인가 JSON Pointer인가
핵심 요약: JSON Pointer는 키로 저장할 수 있는 유일한 주소이고 JSONPath는 쿼리 언어입니다. 잘못 쓰면 설정 업데이트가 깨지거나 망가진 JSONPath를 재발명합니다.

핵심부터 말하면, 노드 하나를 읽고 쓰거나 주소를 저장해야 하면 JSON Pointer(예: /server/cors/0), 조건으로 노드 집합을 선택해야 하면 JSONPath를 쓰세요. 영속화되는 경로는 항상 Pointer여야 하고 절대 표현식이면 안 됩니다.
하나의 노드가 필요한지 집합이 필요한지 물으세요.
한 표로
| JSON Pointer | JSONPath | |
|---|---|---|
| 본질 | 유일한 주소 | 쿼리 표현식 |
| 문법 | /a/b/0 |
$.a.b[0], $..price |
| 결과 | 정확히 하나의 노드, 또는 없음 | 0개 이상의 노드 |
| 키로 저장 가능 | 예, 문자열이 정체성 | 아니요, 여러 개를 매칭할 수 있음 |
| 표준 | RFC 6901 | RFC 9535(2024 확정) |
JSON Pointer
/server/host -> "127.0.0.1"
/server/cors/0 -> "https://a.com"
/ -> the whole document
/나 ~가 든 키는 이스케이프합니다. ~는 ~0, /는 ~1. 가치는 결정성입니다. 주소가 문자열이라 데이터베이스 열, 로그 줄, 설정 키에 들어갑니다. JSON Patch(RFC 6902)가 모든 연산을 이렇게 지목합니다.
JSONPath
$.store.book[*].author
$..price
$.store.book[?(@.price < 10)]
SQL WHERE에 더 가깝습니다. 같은 표현식이 데이터에 따라 0개, 하나, 백 개 노드를 반환합니다.
두 실패 모드
JSONPath를 설정 키로 쓰기. $.server.port를 저장했는데 어느 날 구조가 배열이 됩니다. 표현식이 이제 여러 포트를 매칭하고 업데이트 로직이 고를 방법이 없습니다.
선택에 Pointer 쓰기. "가격이 10 미만인 모든 노드 찾기"는 포인터로 불가능합니다. 루프를 직접 쓰는 것은 부분적 JSONPath를 만드는 일입니다.
실제 시스템의 분업
- 설정 읽기, 필드 업데이트, 패치: Pointer, 고정되고 감사 가능
- 데이터 탐색, 대량 추출, 리포트: JSONPath, 표현력 우선
- 영속화되는 모든 것: Pointer만, 표현식은 절대 안 됨
FAQ
JSON Pointer와 JSONPath 중 어떻게 고르나?
하나의 노드가 필요한지 집합이 필요한지 물으세요. 특정 노드 하나를 읽고 쓰며 그 주소를 키로 저장하려면 JSON Pointer를 쓰세요. 포인터가 유일하기 때문입니다. 예: /server/cors/0. 조건으로 노드를 선택하려면 JSONPath를 쓰세요. 예: $.store.book[?(@.price < 10)].
JSONPath 표현식을 설정 키로 쓸 수 없는 이유는?
표현식이 여러 노드를 매칭할 수 있기 때문입니다. $.server.port를 저장했는데 어느 날 구조가 배열이 되면 표현식이 여러 포트를 매칭하고 업데이트 로직이 어느 것을 바꿀지 결정할 수 없습니다. 영속화되거나 감사되는 모든 것은 Pointer가 필요합니다.
JSON Pointer가 조건으로 노드를 필터할 수 있나?
아니요. 포인터는 고정 경로만 순회하고 어떤 노드가 존재하는지 알 방법이 없어 가격이 10 미만인 모든 노드를 선택하는 것이 불가능합니다. 그 루프를 직접 쓰는 것은 부분적 JSONPath를 만드는 일입니다.