How to Query Nested JSON with JSONPath (Without Writing Loops)

Published: (May 2, 2026 at 09:21 PM EDT)
4 min read
Source: Dev.to

Source: Dev.to

Introduction

You just got back a 300‑line API response. Somewhere inside three levels of nesting is the email field you actually need. Writing nested loops quickly becomes brittle when the API schema shifts.
JSONPath offers a concise, read‑only query language for JSON, similar to XPath for XML. Once you learn the syntax, you’ll reach for it constantly.

Example API response

{
  "store": {
    "orders": [
      {
        "id": 1,
        "customer": { "name": "Alice", "email": "alice@example.com" },
        "items": [{ "sku": "A1", "qty": 2 }, { "sku": "B3", "qty": 1 }]
      },
      {
        "id": 2,
        "customer": { "name": "Bob", "email": "bob@example.com" },
        "items": [{ "sku": "C7", "qty": 5 }]
      }
    ]
  }
}

Getting every customer email

JSONPath expression

$.store.orders[*].customer.email

Result

["alice@example.com", "bob@example.com"]
  • $ – root element
  • . – navigate into an object key
  • [*] – all array elements

Filtering by a condition

To retrieve only items where qty is greater than 1:

Expression

$.store.orders[*].items[?(@.qty > 1)]

Result

[
  { "sku": "A1", "qty": 2 },
  { "sku": "C7", "qty": 5 }
]
  • ?() – filter expression
  • @ – current node

Comparison with explicit loops (Python)

# Without JSONPath — five lines, easy to get wrong
results = []
for order in data["store"]["orders"]:
    for item in order["items"]:
        if item["qty"] > 1:
            results.append(item)

The JSONPath version is a single, self‑documenting line.

Recursive descent

When you don’t know the exact location of a key, use the recursive descent operator ..:

$..email

This finds every email field at any depth in the document—handy for exploring unfamiliar schemas.

Practical three‑step workflow

  1. Beautify – Paste the response into a JSON Beautifier to get a clean, indented view.
  2. Validate – Run it through a JSON Validator to ensure it’s well‑formed (malformed payloads return empty results).
  3. Query – Use a JSONPath tool (e.g., the JSONPath Evaluator on jsonindenter.com) to iterate on your expression until you extract exactly what you need.

JSONPath syntax cheat sheet

SymbolMeaning
$Root element
.keyChild key
..keyRecursive search for key at any depth
[*]All array elements
[0]First element ([-1] – last element)
[0,2]Elements at index 0 and 2
[?(@.price < 10)]Filter where price is less than 10
@.keyCurrent node’s key (inside filter expressions)

Implementation notes

  • Pythonjsonpath-ng
  • JavaScriptjsonpath-plus
  • Java – Jayway JSONPath

Implementations differ slightly. RFC 9535 (published 2024) is working toward standardization, but for production code you should test expressions against the specific library you use.

When to use JSONPath vs. JSON Patch

JSONPath is read‑only: it queries and extracts data.
If you need to modify a JSON document (add, replace, or remove fields), use JSON Patch (RFC 6902). The two tools complement each other: JSONPath to find, JSON Patch to modify.

Conclusion

JSONPath makes complex JSON queries composable and readable. A well‑written expression communicates intent at a glance, while nested loops force the reader to work through the entire block before understanding the extraction. Because the same expression works across JavaScript, Python, Java, and tools like Postman, learning JSONPath pays off across your entire stack.

Free tools referenced

  • JSONPath Evaluator – test JSONPath expressions live in the browser.
  • JSON Beautifier – format raw JSON for easy reading.
  • JSON Validator – verify that JSON is well‑formed before querying.
  • JSON Patch – apply RFC 6902 patches to modify JSON structures in place.
0 views
Back to Blog

Related posts

Read more »

What’s Your Fear Score as a Developer?

Fear costs us everything. I once heard the quote, “You miss 100% of the shots you don’t take,” and it resonated throughout my career. Looking back, I missed man...