Posts
IETF JSONPath for The Rust Programming Language

Posted: 03 December 2023

Earlier this year, I published the serde_json_path crate, a library that allows you to leverage IETF JSONPath in your Rust programs. This article provides an introduction to serde_json_path and some of its derivatives.

Update (23 February 2024): The JSONPath standard has been published as RFC 9535

What is IETF JSONPath?

JSONPath, a tool for querying and extracting nodes from JSON objects, was originally described by Stefan Gössner in 2007. Gössner's articles have been the basis for JSONPath's widespread adoption and implementation. Most existing implementations of JSONPath, including those available to the Rust Programming Language, use them as a framework.

Recently, the IETF formed a working group to standardize JSONPath. Led by the same Stefan Gössner, as well as Glyn Normington and Carsten Bormann, the group has produced an extensive, clear, and precise standard for JSONPath. You can read the document in various formats here. It will likely be published as an RFC by early 2024.

The serde_json_path crate

I generally use the serde_json crate to work with JSON in Rust. Some time ago, I had a use for JSONPath. A keyword search for "jsonpath" on crates.io reveals that there are several JSONPath implementations available to Rust programmers; however, I did not feel the API or documentation of these crates was up to the standard of quality set by the Rust ecosystem.

I published the serde_json_path crate to provide Rust developers with a JSONPath implementation that:

  • is fully compliant with the IETF JSONPath specification,
  • provides a concise and idiomatic API that is thoroughly documented, and
  • integrates with serde_json.

The resulting API provides two key abstractions: JsonPath and NodeList. Here is a brief example:

use serde_json::json;
use serde_json_path::JsonPath;

let value = json!({
    "foo": ["bar", "baz"]
});

let path = JsonPath::parse("$.foo.*").expect("valid JSONPath");
let nodes = path.query(&value).all();
assert_eq!(nodes, vec!["bar", "baz"]);

An instance of JsonPath represents a parsed and valid JSONPath expression. It can be instantiated with the parse method as above, but the type also implements serde::Deserialize, so it can be deserialized directly from, e.g., configuration files. JsonPath provides a single method query to perform the query and produce a NodeList.

Have a look at the crate documentation for a broad overview of JSONPath capability and how to use serde_json_path. I also encourage readers to check out the IETF standard to understand the nitty-gritty details of what they can do with their JSONPath queries.

A note on compliance

Although not officially affiliated with the IETF working group, a compliance test suite (CTS) is being actively developed to establish compliance of JSONPath implementations with the IETF standard. serde_json_path is kept up-to-date with the CTS to ensure that it covers all the corners and edge cases of the specification.

WASM and JSONPath Sandbox

You can try out IETF JSONPath in the sandbox environment. The sandbox parses and executes JSONPath queries entirely in the browser by utilizing the serde-json-path NPM package– which takes serde_json_path and compiles it to WASM.


See a problem with this post? Please feel free to submit an issue on Github.