How would you send the same request to multiple endpoints based on a list?

I have a scenario that loads a page and reads four RESTful services that return JSON objects.

I need to build a single JSON object to send back to the server, but I need to conditionally send it back based on what was in those JSON objects. Specifically, if the first service had zero objects returned, I skip it. If it had one, I send a request to the server with my built object. If it has two or more, I send a response to the server for each one. I need to repeat that with different URLs for each of those objects.

If I were doing this declaratively, or in native scala, I would just loop over the objects returned by the restful service and compose the appropriate URL and then send it.

What is the “Gatling-Way” of doing that?

It appears to be .foreach() which I’m playing with. However, all is not well, yet…

I’m doing something like this:

.exec( session => session.set( THE_ID_LIST, “” ) )

.check( jsonPath("$.result[*].id" ).findAll.dontValidate.saveAs( THE_ID_LIST )

.exec( session => {
println( "THE_ID_LIST: " + session( THE_ID_LIST ).as[String] ) // THE_ID_LIST: Vector()
session
})

.doIf( session => session( THE_ID_LIST ).as[String] != “” ) {
foreach( THE_ID_LIST, THE_ID ) {

}
}

Now, looking at the documentation, foreach takes a string, uses that as the key to find the Iterable in the Session, and iterates over it. THE_ID_LIST is a string constant. Clearly, the session contains a key for that string. But when I run it, I get an error:

13:44:19.139 [ERROR] i.g.c.s.LoopBlock$ - Condition evaluation crashed with message ‘Can’t cast value theIdList of type class java.lang.String into interface scala.collection.Seq’, exiting loop

Looks like we have a bug in there somewhere. FYI, I just tested with 2.0.0-RC1, same problem.

Thanks!

On a whim, I tried modifying it to:

.foreach( “${” + THE_ID_LIST + “}”, THE_ID ) {

and it looks like it may have actually worked. Is that the way it is supposed to be?

Hi,

.check( jsonPath("$.result[*].id" ).findAll.dontValidate.saveAs( THE_ID_LIST )

Can you try with .find instead ?

thanks
Nicolas

Does .find with a wildcard operate the same as .findAll()? Because the .findAll part is working fine.

The part that is not visible in my code snippet is this:

val THE_ID_LIST = “theIdList”

If I take out that indirection, it might become more clear what is going on:

foreach( “theIdList”, “theId” ) {

Does NOT work, but…

foreach( “${theIdList}”, “theId” ) {

Does. Is that expected behavior?

Hi John,

This in an expected behaviour : foreach’s first parameter takes is an Expression[Seq[Any]], meaning an EL expression which resolves to a list or a function which takes a Session and returns a list.

This explains why “theIdList”, which is not an EL string, does not work whereas “${theIdList}” does.

However, the documentation is not exactly clear on that matter, I’ll make sure to clear that out :wink:

Cheers,

Pierre

Thanks, guys!