Request body built from conditional checks

I’m trying to model a scenario where an initial request will provide several different lists of Ids, then a later request needs to submit the values in these lists (if they exist) as part of it’s JSON payload. None of the lists is guaranteed to be in the response, and if it isn’t, then there is no corresponding entry at all for it in the later JSON.

For example, call 1 might return 3 different lists of Ids that can be saved for later calls…

.check(
  jsonPath("$..manager").findAll.optional.saveAs("managemerIds"),
  jsonPath("$..employee").findAll.optional.saveAs("employeeIds"),
  jsonPath("$..temp").findAll.optional.saveAs("tempIds")      
)

Later I need to submit these as a request body formatted like

{"managers":"${managerIds.jsonStringify()}",
 "employees":"${employeeIds.jsonStringify()}",
 "temps":"${tempIds.jsonStringify()}"}

but if one of the lists of Ids is empty, then it can’t be submitted in the JSON at all - ie: if there were no tempId’s from the first request, then the JSON payload needs to look like

{"managers":"${managerIds.jsonStringify()}",
 "employees":"${employeeIds.jsonStringify()}"}

I could get this working by using a transformOption on the check to set the session variable to an empty list and then have conditional building of the JSON payload by doing something like

jsonPath("$..temp").findAll.transformOption(ids => ids.orElse(Some(Seq.empty[String])).success).saveAs("tempIds"))

but I was hoping for something more idiomatic using gatling Expressions or maybe Options

I can generate the required JSON for the body this way with something like

private def createPayload(
    managers: Option[String] = None, 
    employees: Option[String] = None, 
    temps: Option[String] = None) : String = {

        Map("managers" -> managers,
            "employees" -> employees,
            "temps" -> temps
        ).foldLeft(JsObject.empty){ case (result, (key, values)) => {
        values match {
          case Some(ids) => result ++ result.transform((__ \ key).json.put(JsString(ids))).get
          case None => result
      }
    }}.toString()

but I can’t work out a way to just pass the option that results from attempting to resolve the session variable

I ended up with something like this… which I’m quite happy with. The contactPeople function can now take session variables or just explicitly provided sequences

`

def contactPeople(managers: Expression[Seq[String]], employees: Expression[Seq[String]], temps: Expression[Seq[String]]: ChainBuilder = {
exec(http(...)
  .post(...)
  .headers(...)
  .body(StringBody(session =>
     Map("managers" -> managers, "employees" -> employees, "temps" -> temps)
     .foldLeft(JsObject.empty){ case (result, (key, values)) => {
         values.apply(session) match {
             case Success(ids) => result ++ result.transform((__ \ key).json.put(Json.toJson[Seq[String]](ids))).get
             case Failure(error) => result
         }
     }}.toString
  ))
  ...
}

`