Adding X-Access-Token header to HttpRequests based on data within the Session

Hi,

I’m trying to learn Gatling, so sorry if this is the wrong forum. I’ve tried searching for this and couldn’t find any inside information.

Currently I’m working on a Gatling suite for an API that I’m working on, and this API is used by first acquiring an access token that is part of a session response; and with the access token subsequently being added as a header for each and every request.

I could manually add the header for each and every request that I make to the API, however this seems quite redundant.

Is there a recommended approach for adding a session token to each and every http call BUT the one that returns the token in the first place?

Best,

Henrik

You can save the token in session and re-use it.

Look here for an example.

Abhinav

Thanks a lot Abhinav,

Saving into my Session I’m all cool with, it is on subsequent calls where I would like having to avoid explicitly mentioning the header that is to be set.

Gatling scenarios are written in Scala, which is a high-level language. That means you can leverage those high-level language features to avoid that redundancy by creating a pattern of objects and classes that are smart enough to automatically do the right thing.

What you are doing is something that I had to do some time ago. If you look through the group archives for messages posted by me, you will even find code samples.

Just to followup, in case anyone may be having the same challenge.

The way that I have solved it, at the moment is by having a package.object that I use in my models/ package, and then overriding HTTP methods in a helper object.


package object models {

 implicit def apiHttp(requestName: Expression[String]):HttpHelper = new HttpHelper(requestName)

}

My HttpHelper object is looking like


class HttpHelper(requestName: Expression[String]) extends Http(requestName: Expression[String]) {

 private final val SESSION_TOKEN = "X-Session-Token"

 override def get(url: Expression[String]) = httpRequest("GET", url).header(SESSION_TOKEN, "${session_token}")

 override def get(uri: Uri) = httpRequest("GET", Right(uri)).header(SESSION_TOKEN, "${session_token}")

 override def put(url: Expression[String]) = httpRequest("PUT", url).header(SESSION_TOKEN, "${session_token}")

 override def post(url: Expression[String]) = httpRequest("POST", url).header(SESSION_TOKEN, "${session_token}")

 override def patch(url: Expression[String]) = httpRequest("PATCH", url).header(SESSION_TOKEN, "${session_token}")

 override def head(url: Expression[String]) = httpRequest("HEAD", url).header(SESSION_TOKEN, "${session_token}")

 override def delete(url: Expression[String]) = httpRequest("DELETE", url).header(SESSION_TOKEN, "${session_token}")

 override def options(url: Expression[String]) = httpRequest("OPTIONS", url).header(SESSION_TOKEN, "${session_token}")

}

For all requests, but the initial one I then use ‘apiHttp’ instead of ‘http’, example:


val items = {
 exec(apiHttp("history-items")
 .get("/v1/history/items)
 )
}

My initial request, that is to take place at least once during a virtual user session saves the session_token into the session.


exec(http("sessions-get")
 .post("/v1/sessions")
 .body(StringBody(Json.stringify(jsonBody)))
 .check(
 status.is(201),
 jsonPath("$.session_token").saveAs("session_token")
 )
)

That is a very clean approach.

A note from someone who has been there: This works by extending the Gatling internals. Gatling internals are subject to change. And they do. Be prepared to have your code break at some point in the future when you upgrade to a newer version. Not discouragement at all, just want you to plan accordingly.

Thanks John,

You’re absolutely right! It was with somewhat mixed feelings I did this, as I essentially hook into what could well be perceived to be an implementation detail, yet the upside is that is somewhat isolated; meaning that it hopefully won’t be too much of a pain when I upgrade my Gatling version.