Optional Json Extraction

Hey Everyone,

So I’ve been having lots of fun building up gatling scenarios etc. How ever I’ve got to problems.

One is extracting an array of integers from a JSON body, I’ve currently used this approach, but something tells me there aught to be a better way:

exec(
http(“Show Course”)
.get(s"/api/courses/${courseId}")
.check(
jsonPath("$.conceptIds")
.find

// so I don’t know how to pull an array of primatives out.
// so assuming the data is of the format “conceptIds”: [int, int, int ,int]
// the following pulls it out as a string, removes the array braces, splits
// into a list of roughly ints plus or minus some white space and converts
// them to a list of integers
.transform(str => str.substring(1, str.length - 1).split(’,’).map(_.toInt).toList)
.saveAs(“conceptIds”)
)
)

Similarly I’ve encountered an issue when I am trying to extract a list of keys from an array of objects, it works fine when there are objects in the array, however it looks like it fails when there are no objects in the array. Again some example code, which functions when each of the arrays contain objects:

def doGroupedCourses =
exec(
http(“Grouped Courses”)
.get(s"/api/courses/grouped")
.check(
jsonPath("$.completed[].id")
.findAll
.transform(.map(.toInt))
.saveAs(“completedCourseIds”)
)
.check(
jsonPath("$.notStarted[
].id")
.findAll
.transform(.map(.toInt))
.saveAs(“notStartedCourseIds”)
)
.check(
jsonPath("$.discoverable[].id")
.findAll
.transform(.map(.toInt))
.saveAs(“discoverableCourseIds”)
)
.check(
jsonPath("$.inProgress[
].id")
.findAll
.transform(.map(.toInt))
.saveAs(“inProgressCourseIds”)
)
)

Any guidance would be greatly appreciated, I assume there’s some findAllOptional case I’m missing, or possible a JSON path def I’m missing.

ofType[Int]
http://gatling.io/docs/2.0.0/http/http_check.html#http-response-body

That fails written as such:

exec(
http(“Show Course”)
.get(s"/api/courses/${courseId}")
.check(
jsonPath("$.conceptIds")
.ofType[Int]
.findAll

// so I don’t know how to pull an array of primatives out.
// so assuming the data is of the format “conceptIds”: [int, int, int ,int]
// the following pulls it out as a string, removes the array braces, splits
// into a list of roughly ints plus or minus some white space and converts
// them to a list of integers
// .transform(str => str.substring(1, str.length - 1).split(’,’).map(_.toInt).toList)
.is(List(5,4,3,2,1))
.saveAs(“conceptIds”)
)
)

Unless you mean something else.

I would expect.

.find.ofType[Seq[int]] - which also fails.

Aside: the doc would be much more helpful with imports and example body content. An example of making a method call while useful for syntax, is not entirely useful for determining how it might interact with actual json endpoints.

Sorry, were you pointing me at regex extraction ?

Ok so this works for the first part of my question:

exec(
http(“Show Course”)
.get(s"/api/courses/${courseId}")
.check(
jsonPath("$.conceptIds")
.ofType[Seq[Any]]
.find
.transform(.map(.toString.toInt))
.is(List(5,4,3,2,1))
.saveAs(“conceptIds”)
)
)

Which is better than my Regex and parsing mess before, but still the transform step seems needless, I should be able to specify Seq[Int] which should infer the transform step.

Additionally, the type coercion solves half of the second part of the problem… but I’m still stuck on optional values, eg:

def doGroupedCourses =
exec(
http(“Grouped Courses”)
.get(s"/api/courses/grouped")
.check(
jsonPath("$.notStarted[].id")
.ofType[Int]
.findAll
.saveAs(“notStartedCourseIds”)
)
.check(
jsonPath("$.completed[
].id")
.ofType[Int]
.findAll
.saveAs(“completedCourseIds”)
)
.check(
jsonPath("$.discoverable[].id")
.ofType[Int]
.findAll
.saveAs(“discoverableCourseIds”)
)
.check(
jsonPath("$.inProgress[
].id")
.ofType[Int]
.findAll
.saveAs(“inProgressCourseIds”)
)
)

notStarted is an empty array san so the findAll (I assume) is failing. So perhaps a findAllOption ?

Aside: the doc would be much more helpful with imports and example body content. An example of making a method call while useful for syntax, is not entirely useful for determining how it might interact with actual json endpoints.

We love contributions :slight_smile:
https://github.com/gatling/gatling/blob/master/src/sphinx/http/http_check.rst

Additionally, the type coercion solves half of the second part of the problem… but I’m still stuck on optional values

Then “optional” sounds like a good keyword to search the documentation (textbox in banner) or directly in the HTTP check page.

Somehow I wasn’t able to see that last night, probably too many hours of programming - rushed projects etc.

I’d be happy to contribute to the doc, but perhaps an out of band conversation about the general examples is warranted? I don’t feel like I know enough about the tool yet to specifically contribute. I know I just got stuck for a while figuring out which imports were needed, and where some of the calls hung together because the examples were fragments.

Specifically around the jsonPath parts, and what find calls to make, I eventually figured it out - just offering some feed back :slight_smile:

.joe