JmesPath is not finding a JSON Object

A request responds with a body similar to the following

{
"status":"GOOD",
"fruits":[
  {
    "name":"Apple",
    "details": {
       "size":500
      }
  },
  {
    "name":"Cherry",
    "details": {
        "size":100
      }
  }]
}

I want to apply a JmesPath that contains a filter so that I only get back the first Fruit Object with size >= 500
The JmesPath I came up with is fruits[?details.size >= '500']|[0] This path works correctly on the JmesPath site. However, it does not work in gatling. Gatling says it could not find an object with that JmesPath, specifically ...find.transform.exists, found nothing

My check in my request

.check(
	jmesPath("fruits[?details.size >= '500']|[0]")
		.ofMap()
		.saveAs("fruitObj")
)

I can get a list all fruits with the path "fruits" and the corresponding check of ofList()

I can get a JSON object if I use "fruits[0]" and the check ofMap().

I can not get a list of fruits if I use the following
fruits[?details.size >= '1'] with ofList()

Am I using JmesPath incorrectly?

I have make a test of your problem :slight_smile:
I created mocked service by Wiremock:

{
    "request": {
        "method": "GET",
        "url": "/api/hmmm"
    },
    "response": {
		"headers": {
            "Content-Type": "application/json"
        },
        "status": 200,
        "body": "{\"status\":\"GOOD\",\"fruits\":[{\"name\":\"Apple\",\"details\":{\"size\":500}},{\"name\":\"Cherry\",\"details\":{\"size\":100}}]}"
    }
}

and created Simple Simulation:

import io.gatling.javaapi.core.ScenarioBuilder;
import io.gatling.javaapi.core.Simulation;
import io.gatling.javaapi.http.HttpProtocolBuilder;

import static io.gatling.javaapi.core.CoreDsl.*;
import static io.gatling.javaapi.http.HttpDsl.http;

public class JmeshPathSimulation extends Simulation {

    HttpProtocolBuilder httpProtocol =
            http
                    .baseUrl("http://127.0.0.1:8080");
    ScenarioBuilder scn =
            scenario("Scenario Name")
                    .exec(
                            http("request_1")
                                    .get("/api/hmmm")
                                    .check(
                                            jmesPath("fruits[?details.size >= `500`]").ofList()
                                                    .saveAs("fruitObj")
                                    )
                    ).exec(session -> {
                        System.out.println(session.get("fruitObj").toString());
                        return session;
                    });

    {
        setUp(scn.injectOpen(atOnceUsers(1)).protocols(httpProtocol));
    }
}

and everything is working :smiley:
I think that you have '500' but you must have `500` when you using for filtering numbers.

1 Like

You were absolutely correct. It has to be back ticked, so `500` not ‘500’.

For some reason the JmesPath site does not differentiate between the two if you use their sandbox space. The specification does list the difference.

literal = ` json-value`

Tip: I tend to use https://postman-echo.com to test this, so I don’t have to set up anything such as Wiremock.

1 Like

Nice tip.
Sometimes (at work all times;)) I like to have everything locally and using Wiremock (standalone jar) is good choise.

Just for the record: accepting ' (simple quote) for wrapping literals is not correct according to the JMESPath specification.

literal           = "`" json-value "`"

IMHO, the implementation used on the website accepting simple quotes is a bug. I will try to report it.

You have a little bug in post:


should be:
literal = "`" json-value "`"

Looking at Documentation I do not agree with you, such writing of literals is correct for Strings or I don’t understand correctly Documentation.
https://jmespath.org/specification.html#raw-string-literals

Fixed it, thanks a lot!

1 Like

This is indeed a bug in the JavaScript JMESPath implementation (discussed on the JMESPath official chat) that’s used for the online evaluator.
I’ve opened a ticket there: Numeric literals can only wrapped with backticks, not single quotes · Issue #85 · jmespath/jmespath.js · GitHub

1 Like

Yeah, you are right - in the case shown in the issue (for numbers) :slight_smile:
When I write about my disagree I meant that for numbers should be:
fruits[?details.size >= `500`]
but for Strings can be:
fruits[?name == `"Apple"`]
fruits[?name == 'Apple']