What JSONPath Is For
JSONPath is a tiny query language that lets you extract values from JSON without writing recursion. It was first proposed by Stefan Goessner in 2007, modelled on XPath for XML, and formalised as RFC 9535 in February 2024. Think of it as CSS selectors for JSON — write a short expression, get back every matching value.
Common uses: pulling specific fields from an API response, writing assertions in integration tests (Postman, REST Assured, Karate), extracting data for monitoring dashboards, and defining field mappings in low-code ETL tools.
Example Document
The classic Goessner example — a bookstore with four books:
{
"store": {
"book": [
{ "category": "reference", "author": "Nigel Rees", "title": "Sayings", "price": 8.95 },
{ "category": "fiction", "author": "Evelyn Waugh", "title": "Sword", "price": 12.99 },
{ "category": "fiction", "author": "Herman Melville","title": "Moby Dick", "price": 8.99, "isbn": "0-553-21311-3" },
{ "category": "fiction", "author": "J.R.R. Tolkien", "title": "LOTR", "price": 22.99, "isbn": "0-395-19395-8" }
],
"bicycle": { "color": "red", "price": 19.95 }
}
}Core Expressions, One by One
Field Access
$.store.bicycle.color
// → "red"
$["store"]["bicycle"]["color"] // same, bracket form
// → "red"All Elements of an Array
$.store.book[*].author
// → ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J.R.R. Tolkien"]Recursive Descent
$..author // every author at any depth
$..price // every price (books and bicycle)
$..* // every value at any depthIndex and Slice
$.store.book[0] // first book
$.store.book[-1] // last book (negative indexing, RFC 9535)
$.store.book[0,2] // first and third
$.store.book[0:2] // slice: index 0 and 1
$.store.book[::2] // every second bookFilters
$..book[?(@.price < 10)]
// → books cheaper than $10
$..book[?(@.author == "J.R.R. Tolkien")]
$..book[?(@.isbn)]
// → books that HAVE an isbn field (truthy test)
$..book[?(@.category == "fiction" && @.price < 20)]JSONPath vs jq vs JSON Pointer
- JSONPath — read-only queries. Perfect for extracting data. Multiple matches at once. Filters. Available in every major language.
- jq — Turing-complete transformation language. Can reshape, compose, pipe. Overkill for simple extraction, perfect for shell pipelines.
- JSON Pointer (RFC 6901) — addresses one specific node by exact path (
/store/book/0/author). Used in JSON Patch and JSON Schema errors. No wildcards, no filters.
Library Choices
- JavaScript:
jsonpath-plus(RFC 9535 compatible),jsonpath(older, Goessner spec). - Python:
jsonpath-ng(most popular),jsonpath-rw(older). - Java:
com.jayway.jsonpath— the de facto standard, used by REST Assured. - Go:
github.com/PaesslerAG/jsonpath. - Postman: built-in via
pm.response.json()plus JSONPath in the Tests tab.
Common Pitfalls
- Dialect drift. JSONPath predates RFC 9535. Older libraries may not support
parent,length(), or logical||inside filters. Check your implementation's README. - Filter string quoting. Some libraries require single quotes (
@.author == 'Tolkien'), others require double quotes inside the expression. Our tester accepts both. - Dot-notation for keys with special chars.
$.foo-baris ambiguous (subtraction? field access?). Always use bracket notation for keys with hyphens, dots, or spaces:$["foo-bar"]. - JSONPath result is always a list. Even
$.foo(looks like a single value) returns["value"]in most libraries. Callresult[0]or set a "first match only" flag.
Related JSON Tools
- JSON Formatter — the parent tool.
- JSON Key-Value Extractor — simpler flat extractor.
- JSON Tree Viewer — explore structure before writing paths.
- JSON Flattener — alternative extraction via dot-notation keys.
- Validate JSON — make sure the input parses first.