JSONPath는 JSON을 위한 쿼리 언어로, XML의 XPath와 유사합니다. 간결한 표현식 구문을 사용하여 깊게 중첩된 JSON 구조에서 특정 값을 추출할 수 있습니다. JSONPath 테스터 온라인을 사용하면 JSON을 붙여넣고 표현식을 작성하여 코드 실행 없이 즉시 일치 결과를 확인할 수 있습니다.
JSONPath 구문 기초
모든 JSONPath 표현식은 루트 $에서 시작하여 연산자를 사용해 구조를 탐색합니다.
루트와 점 표기법
{
"store": {
"name": "Tech Books",
"inventory": [
{ "title": "JavaScript: The Good Parts", "price": 29.99, "inStock": true },
{ "title": "Clean Code", "price": 34.99, "inStock": false },
{ "title": "The Pragmatic Programmer", "price": 39.99, "inStock": true }
]
}
}
| 표현식 | 결과 |
|---|---|
$.store.name | "Tech Books" |
$.store.inventory[0].title | "JavaScript: The Good Parts" |
$.store.inventory[2].price | 39.99 |
대괄호 표기법
점 표기법과 동일하지만, 키에 공백이나 특수 문자가 포함된 경우 필수입니다:
$.store['name'] → "Tech Books"
$.store.inventory[0] → 첫 번째 도서 객체
$.store.inventory[-1] → 마지막 도서 객체 (음수 인덱싱)
와일드카드 *
객체의 모든 자식 또는 배열의 모든 요소에 일치:
$.store.inventory[*].title
→ ["JavaScript: The Good Parts", "Clean Code", "The Pragmatic Programmer"]
$.store.*
→ ["Tech Books", [...inventory 배열...]]
배열 슬라이스
Python 스타일 슬라이스 구문 [start:end:step]:
$.store.inventory[0:2] → 처음 두 권
$.store.inventory[::2] → 한 칸씩 건너뛴 도서 (인덱스 0, 2, 4...)
$.store.inventory[-1:] → 마지막 한 권만
재귀적 탐색 ..
이중 점 연산자는 중첩 깊이와 관계없이 전체 트리에서 일치하는 키를 검색합니다:
{
"orders": [
{ "id": 1, "customer": { "name": "Alice" } },
{ "id": 2, "customer": { "name": "Bob" } }
]
}
$..name
→ ["Alice", "Bob"]
$..id
→ [1, 2]
이는 API에서 깊게 중첩되거나 일관성 없는 구조의 JSON 응답을 탐색할 때 특히 유용합니다.
필터 표현식 ?()
필터 표현식은 조건에 일치하는 요소를 선택합니다. @은 현재 요소를 참조합니다:
$.store.inventory[?(@.inStock == true)].title
→ ["JavaScript: The Good Parts", "The Pragmatic Programmer"]
$.store.inventory[?(@.price < 35)].title
→ ["JavaScript: The Good Parts", "Clean Code"]
$.store.inventory[?(@.price >= 35)]
→ [{ "title": "Clean Code", ...}, { "title": "The Pragmatic Programmer", ...}]
지원되는 비교 연산자: ==, !=, <, <=, >, >=.
일부 구현에서는 다음도 지원합니다:
- 정규식 매칭
=~:[?(@.title =~ /Code/i)] - 멤버십
in:[?(@.category in ['tech', 'science'])]
실제 JSONPath 예시
API 응답 탐색
REST API는 깊게 중첩된 데이터를 자주 반환합니다. JSONPath로 필요한 정보에 바로 접근할 수 있습니다:
{
"data": {
"users": [
{ "id": 1, "profile": { "email": "alice@example.com", "role": "admin" } },
{ "id": 2, "profile": { "email": "bob@example.com", "role": "user" } }
]
},
"meta": { "total": 2 }
}
$.data.users[*].profile.email
→ ["alice@example.com", "bob@example.com"]
$.data.users[?(@.profile.role == "admin")].id
→ [1]
$.meta.total
→ 2
설정 파일 쿼리
JSON 설정 파일은 Node.js와 Python 프로젝트에서 일반적입니다:
{
"database": {
"host": "localhost",
"port": 5432,
"credentials": { "username": "app", "password": "secret" }
},
"cache": {
"host": "redis-host",
"port": 6379
}
}
$..host
→ ["localhost", "redis-host"]
$..port
→ [5432, 6379]
$.database.credentials.username
→ "app"
AWS / 클라우드 API 응답
클라우드 API는 복잡한 JSON을 반환합니다. JSONPath로 특정 필드를 추출:
$.Reservations[*].Instances[*].InstanceId
$.Items[?(@.Status == "ACTIVE")].ResourceArn
$..Tags[?(@.Key == "Environment")].Value
다양한 언어에서의 JSONPath
JSONPath는 JSON 자체의 표준 기능이 아니라 각 언어 생태계에서 별도로 구현됩니다.
JavaScript
// jsonpath-plus 사용
import { JSONPath } from 'jsonpath-plus';
const result = JSONPath({ path: '$.store.inventory[*].title', json: data });
Python
from jsonpath_ng import parse
expr = parse('$.store.inventory[*].title')
matches = [match.value for match in expr.find(data)]
Java
// Jayway JsonPath 사용
import com.jayway.jsonpath.JsonPath;
List<String> titles = JsonPath.read(json, "$.store.inventory[*].title");
Go
// gjson 사용
import "github.com/tidwall/gjson"
result := gjson.Get(json, "store.inventory.#.title")
커맨드 라인 (jq)
jq는 고유한 구문을 사용하지만 유사한 목적을 수행합니다:
# JSONPath 동일: $.store.inventory[*].title
echo "$json" | jq '.store.inventory[].title'
# 필터 동일: $.store.inventory[?(@.inStock == true)]
echo "$json" | jq '.store.inventory[] | select(.inStock == true)'
JSONPath vs jq vs XPath
| 기능 | JSONPath | jq | XPath |
|---|---|---|---|
| 입력 형식 | JSON | JSON | XML |
| 재귀적 탐색 | .. | .. | // |
| 필터 표현식 | ?(@.x > 5) | select(.x > 5) | [@x > 5] |
| 변환 | 없음 | 있음 (전체 파이프라인) | 제한적 |
| 표준 | RFC 초안 | 없음 | W3C 표준 |
| CLI 도구 | 없음 | 있음 | xmllint, xmlstarlet |
JSONPath는 데이터를 변환하지 않고 추출하는 쿼리가 필요할 때 적합합니다. 데이터를 변환하거나 재구성해야 할 때는 jq를 사용하세요. XPath는 XML에만 사용합니다.
흔한 JSONPath 실수
$ 누락: 모든 표현식은 $로 시작해야 합니다. store.name은 유효하지 않으며, $.store.name이 올바릅니다.
배열 인덱스 혼동: JSONPath 배열은 0부터 시작합니다. [0]이 첫 번째 요소이며, [1]이 아닙니다.
.과 .. 혼동: 단일 점은 한 레벨을 탐색합니다. 이중 점 ..은 모든 레벨을 재귀적으로 내려갑니다. .key를 의도했는데 ..key를 사용하면 결과는 반환되지만 예상치 못한 중첩 키에 일치할 수 있습니다.
필터 구문 차이: ?() 필터 구문은 구현마다 다릅니다. 사용하는 특정 라이브러리에서 항상 표현식을 테스트하세요.
온라인 JSONPath 테스터
JSONPath 표현식을 코드로 테스트하려면 — 라이브러리 로드, JSON 파싱, 쿼리 작성 — 시간이 걸립니다. JSONPath 테스터는 브라우저에서 완전히 실행됩니다:
- 왼쪽 패널에 JSON 붙여넣기
- JSONPath 표현식 작성 후 즉시 일치 확인
- 원본 JSON 트리에서 결과 하이라이트
- 설치 불필요, 백엔드 없음, API 호출 없음