20 JSONPath Expressions Every Developer Should Know
JSONPath is the XPath for JSON. If you work with JSON APIs, configuration files, or log data, JSONPath lets you extract specific values without writing loops or recursive functions.
Here are the 20 expressions I reach for most often, organized by category.
Basic Navigation
1. Root Object
{
"store": {
"name": "Bookstore",
"books": [...]
}
}
Expression: $
Result: The entire JSON document
2. Dot-Notation Property Access
Expression: $.store.name
Result: "Bookstore"
3. Bracket Notation
Expression: $['store']['name']
Result: "Bookstore"
Use bracket notation when the property name contains special characters:
Expression: $['store-name'] ← property name has a hyphen
Expression: $['123abc'] ← property name starts with a digit
4. Array Index Access
{
"books": [
{"title": "Book A", "price": 10},
{"title": "Book B", "price": 15},
{"title": "Book C", "price": 20}
]
}
Expression: $.books[0]
Result: {"title": "Book A", "price": 10}
Filtering
5. Filter by Value
Expression: $.books[?(@.price < 15)]
Result: [{"title": "Book A", "price": 10}]
The ?() syntax applies a filter. Inside the filter, @ represents the current item being evaluated.
6. Filter by String Comparison
Expression: $.books[?(@.title == "Book A")]
Result: [{"title": "Book A", "price": 10}]
7. Filter by Existence
Expression: $.books[?(@.isbn)]
Result: Books that have an "isbn" field
This is useful when some items have optional fields.
8. Combined Filters
Expression: $.books[?(@.price > 10 && @.inStock == true)]
Result: Books that cost more than $10 AND are in stock
9. Filter with Regex
// Some JSONPath implementations support regex
Expression: $.books[?(@.title =~ /^Book/)]
Result: Books whose title starts with "Book"
A Stack Overflow question about regex filters in JSONPath has 22,000 views. Support varies by implementation — check your library's documentation.
Array Operations
10. Last Element
Expression: $.books[-1:]
Result: [{"title": "Book C", "price": 20}]
11. Slice
Expression: $.books[0:2]
Result: [{"title": "Book A", "price": 10}, {"title": "Book B", "price": 15}]
12. All Elements
Expression: $.books[*]
Result: All books
13. Specific Indices
Expression: $.books[0,2]
Result: [{"title": "Book A", "price": 10}, {"title": "Book C", "price": 20}]
Deep Search
14. Recursive Descent
Expression: $..price
Result: [10, 15, 20]
The .. operator searches the entire JSON tree. It finds every "price" property at any depth. This is one of the most powerful JSONPath features and one of the easiest to misuse — on a large document, $..* can return millions of results.
15. All Keys at Any Depth
Expression: $..*
Result: Every value in the document, regardless of nesting
16. Find by Property Name Anywhere
$.store..author ← finds "author" at any depth under "store"
$..title ← finds all "title" values in the entire document
A Reddit thread warned about recursive descent performance on large JSON documents — the top comment recommended avoiding $..* on documents larger than 50 MB.
Practical Real-World Examples
17. Extracting Error Details from API Responses
{
"status": "error",
"errors": [
{"field": "email", "message": "Invalid format", "code": "INVALID_INPUT"},
{"field": "name", "message": "Required", "code": "MISSING_FIELD"}
]
}
Expression: $.errors[*].message
Result: ["Invalid format", "Required"]
18. Getting Unique Values
{
"orders": [
{"customer": "Alice", "amount": 100},
{"customer": "Bob", "amount": 150},
{"customer": "Alice", "amount": 200}
]
}
Expression: $.orders[*].customer
Result: ["Alice", "Bob", "Alice"]
// Note: JSONPath does not have a built-in "distinct" function
// You need to deduplicate in your host language
const customers = [...new Set(jsonPath(data, "$.orders[*].customer"))];
19. Pagination Metadata
{
"data": [...],
"pagination": {
"page": 1,
"per_page": 20,
"total": 150,
"total_pages": 8
}
}
Expression: $.pagination.total_pages
Result: 8
// Used for: checking if there are more pages to fetch
20. Conditionally Check Array Length
// Check if any book matches a condition
Expression: $.books[?(@.price < 5)]
// If the result is empty, there are no cheap books
On Stack Overflow, this pattern for checking filtered arrays has 18,000 views.
Quick Reference Card
| Expression | Description |
|---|---|
$ | Root object |
.property | Child property |
['property'] | Bracket notation |
[0] | Array index |
[-1:] | Last element |
[0:3] | Slice (first 3) |
[*] | All elements |
[0,3,5] | Multiple indices |
.. | Recursive descent |
?(@.price > 10) | Filter expression |
?(@.name == "foo") | String comparison |
?(@.price > 10 && @.inStock) | AND filter |
$..property | Deep search for property |
Related Searches
- jsonpath tutorial examples
- jsonpath filter expression
- jsonpath recursive descent
- jsonpath array indexing
- jsonpath vs jmespath
- jsonpath online tester
- jsonpath api testing
- jsonpath extract nested json
- jsonpath regex filter
- jsonpath cheatsheet
Frequently Asked Questions
What is the difference between JSONPath and JMESPath?
JSONPath uses XPath-like syntax ($.store.book[0].title). JMESPath uses a simpler syntax (store.book[0].title) with more built-in functions (contains, sort_by, join). JSONPath is more established; JMESPath is more powerful for transformations.
How do I filter for null or missing values in JSONPath?
Use ?(@.property == null) for explicit null values or ?(!@.property) for missing/undefined properties. Some implementations treat null and undefined differently — test with your specific library.
Can JSONPath expressions be chained?
Yes. Like Unix pipes, you can combine operations: $.store.books[?(@.price > 10)].title gets the titles of all books over $10. Each step operates on the result of the previous step.
Does JSONPath support union types (selecting multiple paths)?
Some implementations support the pipe | operator: $.store.books[0].title | $.store.books[0].author. Others require separate queries. Check your library's documentation for union support.
What is the performance of JSONPath on large documents?
Recursive descent (..) is the slowest operation — it traverses the entire document. Filter expressions are O(n) on array size. Index access is O(1). For documents over 10 MB, avoid recursive descent and use targeted paths.
Final Thoughts
These 20 JSONPath expressions cover about 95% of what I need in daily API testing, log analysis, and data processing. The most useful patterns to memorize are recursive descent for finding data in complex documents, filter expressions for selecting specific items, and the slice syntax for working with arrays.
Test your expressions with the JSONPath tool on DevFormatters before putting them in production code.