I have a block of code which needs to loop through a JSON array which is obtained from response of a REST service. (Full gist available here.)
.exec(http("Request_1")
.post("/endPoint")
.headers(headers_1)
.body(StringBody("""REQUEST_BODY""")).asJSON
.check(jsonPath("$.result").is("SUCCESS"))
.check(jsonPath("$.data[*]").findAll.saveAs("pList")))
.exec(session => {
println(session)
session
})
.foreach("${pList}", "player"){
exec(session => {
val playerId = JsonPath.query("$.playerId", "${player}")
session.set("playerId", playerId)
})
.exec(http("Request_1")
.post("/endPoint")
.headers(headers_1)
.body(StringBody("""{"playerId":"${playerId}"}""")).asJSON
.check(jsonPath("$.result").is("SUCCESS")))
}
The response format of the first request was
{
"result": "SUCCESS",
"data": [
{
"playerId": 2
},
{
"playerId": 3
},
{
"playerId": 4
}
]
}
And playerId
shows up in the session as
pList -> Vector({playerId=2, score=200}, {playerId=3, score=200}
I am seeing in the second request the body is
{"playerId":"Right(empty iterator)}
Expected : 3 requests with body as
{"playerId":1}
{"playerId":2}
{"playerId":3}
I can loop over the resulting array successfully if I save just the playerIds:
.check(jsonPath("$.data[*].playerId").findAll.saveAs("pList")))
I managed to get the requests you're looking for sent out (although still getting a 404, but that might be server-side or the request your gist is sending might be missing something). The trick was to give up on JsonPath entirely:
.exec(http("Request_10")
.get("gatling1")
.headers(headers_10)
.check(jsonPath("$.result").is("SUCCESS"),
jsonPath("$.data[*]").ofType[Map[String,Any]].findAll.saveAs("pList")))
.foreach("${pList}", "player") {
exec(session => {
val playerMap = session("player").as[Map[String,Any]]
val playerId = playerMap("playerId")
session.set("playerId", playerId)
})
Here, the jsonPath
check can automatically store your JSON object as a map, and then you can access the player ID by key. The value type doesn't have to be Any
, you could use Int
or Long
if all your values are numbers. If you want more info on what went wrong with JsonPath
, read on.
Your first problem is that JsonPath.query()
doesn't just return the value you're looking for. From the JsonPath readme:
JsonPath.query("$.a", jsonSample) gives you Right(non-empty iterator). This will allow you to iterate over all possible solutions to the query.
Now, when it says Right(non-empty iterator)
, I assumed that meant the iterator was not empty. However, if you try this:
val playerId = JsonPath.query("$.playerId", session("player").as[String]).right.get
println(playerId)
...it prints "empty iterator". I'm not sure whether it's a problem with JsonPath
, the jsonPath
check, or usage somewhere in between, but there's not quite enough documentation for me to want to dig into it.