Yet Another JSON query language: Introducing JMESPath support

Yet Another JSON query language: Introducing JMESPath support

The issue with JsonPath

Gatling has had JsonPath support for many year, since Nicolas Rémond contributed it 2013 (thanks again!).
We even went to the length of having our own implementation because we weren’t satisfied with existing ones in terms of performance and maintainability.

Still, JsonPath suffers from a huge issue at its core that’s very difficult to fix: it lacks a proper specification.
JsonPath was born from a blog post from Stefan Goessner back in 2007, who also created some JS and PHP implementations.
Sadly, there are lots of holes in what’s described in the post. No fully described grammar nor Test Compliance Kit (TCK).

As a consequence, there are lots of implementations out there, including ours, each with their own bugs and their own interpretation of the original paper.
Some of those projects got their hands on the json-path Github organization or on a jsonpath domain. That makes them visible in search engine results, but hardly makes them reference implementations.

The result is a lack of interoperability. If you’re using an online JsonPath evaluator to craft your query, there’s a chance you get a different result or an invalid syntax error (JS implementations tend to be very lax) once running with Gatling.

Don’t get me wrong here: our JsonPath implementation works great, it’s the most efficient implementation on the JVM and we’ll keep on supporting it!
But we felt the need to find a solution that would provide more interoperability.

Why not jq?

jq is pretty popular amongst ops people. It’s typically used to transform JSON responses to feed into a second request.

But it’s a command line tool. It’s neither designed for performance nor provides a specification. You can find re-implementations in other technologies such as Java, but they suffer from the exact same flaws as JsonPath: there’s no way to guarantee they are aligned with the original project. So it’s not something we can considering for integrating in Gatling.

Introducing JMESPath

JMESPath is exactly the standard we were looking for: a complete grammar, a compliance test suite, an official online evaluator and certified implementations in multiple languages, including Java.

Transformations, single result

On contrary to JsonPath, it can apply transformations on the selected nodes, possibly joining multiple results into one object.
This can be used for generating the payload for the next request directly into the check.
Because of those possible transformations, JMESPath always generates one single result, be it an array or an object. Result cardinaly is unrelated to the search results’ so Gatling jmesPath check doesn’t have findAll.

No recursive traversal

Another difference with JsonPath is that JMESPath doesn’t have recursive traversal (// in XPath and .. in JsonPath). You have to specify the full path.

Then, recursive traversal can be seen as a bad practice as it forces to scan the full tree, which can hurt performance on large JSON trees.

Performance

We use (and contribute to) the JMESPath implementation from Burt. It’s typically twice faster as our JsonPath implementation.

Then, usually, performance is largely dominated by JSON parsing, so overall performance is Gatling is pretty similar.

Using in Gatling

We’ve introduced a new check types named jmesPath and jsonpJmesPath.

If you want to give it a try, check the documentation here!

Stephane (@slandelle)

Posted in Tech
Posted on 31 July 2019