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

ExpressionDescription
$Root object
.propertyChild 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
$..propertyDeep 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.