JSONPath is a standardized query language for extracting, filtering, and navigating structured JSON documents. Standardized formally under IETF RFC 9535, JSONPath serves as the JSON counterpart to XML's XPath.
Whether you are asserting payloads in API contract testing (e.g. Postman, REST Assured), parsing complex telemetry logs, or extracting target fields in workflow automations, JSONPath provides declarative query syntax without requiring imperatively nested loops.
This guide provides a comprehensive syntax cheat sheet, filter expression references, real-world query patterns, and a comparison against jq and JMESPath.
1. JSONPath Syntax Cheat Sheet (RFC 9535)
| Syntax Element | Description | Example Expression | Example Match |
|---|---|---|---|
$ |
Root object or array | $ |
The entire document |
@ |
Current node being processed | $[?(@.price < 10)] |
Context node inside filter |
. |
Child operator (dot-notation) | $.store.book |
book property inside store |
['name'] |
Child operator (bracket-notation) | $['store']['book'] |
Useful for keys with spaces or dashes |
.. |
Recursive descent (deep search) | $..author |
All author keys anywhere in the hierarchy |
* |
Wildcard match (all properties or elements) | $.store.book[*] |
All items in the book array |
[n] |
Array subscript index (0-based) | $.store.book[0] |
First book in array |
[-1] |
Negative index (from end) | $.store.book[-1] |
Last book in array |
[start:end:step] |
Array slice notation | $.store.book[0:4:2] |
1st and 3rd books (step by 2) |
[0, 2] |
Multiple index selector | $.store.book[0, 2] |
First and third books |
[?(<expr>)] |
Filter expression | $..book[?(@.price < 15)] |
All books cheaper than $15 |
2. Sample Dataset & Query Examples
Consider the following e-commerce JSON structure:
{
"store": {
"name": "DevFlow Books",
"location": "San Francisco",
"inventory": [
{
"id": "B01",
"title": "Designing Data-Intensive Applications",
"author": "Martin Kleppmann",
"category": "databases",
"price": 38.50,
"inStock": true,
"tags": ["distributed-systems", "architecture"]
},
{
"id": "B02",
"title": "Clean Code",
"author": "Robert C. Martin",
"category": "software-craft",
"price": 29.99,
"inStock": false,
"tags": ["refactoring", "best-practices"]
},
{
"id": "B03",
"title": "Database Internals",
"author": "Alex Petrov",
"category": "databases",
"price": 45.00,
"inStock": true,
"tags": ["storage-engines", "distributed-systems"]
}
]
}
}
Common Query Patterns
-
Extract all book titles across any depth:
$..titleResult:
["Designing Data-Intensive Applications", "Clean Code", "Database Internals"] -
Extract all books currently in stock:
$.store.inventory[?(@.inStock == true)] -
Find titles of database books costing under $40:
$.store.inventory[?(@.category == 'databases' && @.price < 40)].titleResult:
["Designing Data-Intensive Applications"] -
Extract books containing a specific tag:
$.store.inventory[?('distributed-systems' in @.tags)]
3. Filter Operators Reference
Filter expressions inside [?(...)] evaluate boolean conditions against each node in an array or collection:
| Operator | Meaning | Example |
|---|---|---|
== |
Strict equality | @.status == 'ACTIVE' |
!= |
Inequality | @.role != 'GUEST' |
< / <= |
Less than / Less than or equal | @.age <= 21 |
> / >= |
Greater than / Greater than or equal | @.score >= 95.5 |
&& |
Logical AND | @.inStock == true && @.price < 20 |
|| |
Logical OR | @.category == 'dev' || @.category == 'ops' |
! |
Logical NOT | [email protected] |
=~ |
Regular expression match | @.email =~ /.*@company\\.com$/ |
in |
Inclusion in array / subset | 'admin' in @.roles |
4. JSONPath vs. jq vs. JMESPath
Different ecosystems rely on distinct JSON querying standards. Here is how they compare for typical tasks:
| Goal | JSONPath (RFC 9535) | jq | JMESPath |
|---|---|---|---|
| Root element | $ |
. |
@ |
| Deep recursive search | $..author |
.. .author? // empty |
N/A (requires projections) |
| Array filtering | $.items[?(@.price < 10)] |
.items[] | select(.price < 10) |
items[?price < \10`]` |
| Object transformation | Read-only selection | Full functional transform | Object projections {name: title} |
| CLI / Scripts | Libraries in JS/Python/Java | Native standalone CLI | AWS CLI / Azure CLI native |
5. Implementing JSONPath in Code
TypeScript / Node.js (jsonpath-plus)
import { JSONPath } from 'jsonpath-plus';
const data = {
users: [
{ id: 1, name: 'Alice', active: true, balance: 120 },
{ id: 2, name: 'Bob', active: false, balance: 40 },
{ id: 3, name: 'Charlie', active: true, balance: 350 },
],
};
// Query active users with balance > 100
const highValueUsers = JSONPath({
path: '$.users[?(@.active && @.balance > 100)].name',
json: data,
});
console.log(highValueUsers); // Output: ['Alice', 'Charlie']
Python (jsonpath-ng)
from jsonpath_ng.ext import parse
data = {
"services": [
{"name": "auth-service", "status": "UP", "latency": 12},
{"name": "billing-service", "status": "DOWN", "latency": 500},
]
}
query = parse("$.services[?(@.status == 'DOWN')].name")
matches = [match.value for match in query.find(data)]
print(matches) # Output: ['billing-service']
Tip: Interactively test, visualize, and validate JSONPath expressions against live JSON payloads using the DevFlow JSONPath Tester.