I have endpoint which I'll denote as /endpoint
which does something like this
def endPoint() = Action.async { implicit request =>
val result: Result = Ok("Done")
result.addingToSession("Key" -> "Value"): Result
}
When I send a WSRequest
to the endpoint and get the WSResponse
back, I can't seem to find the "Key","Value"
pair that was added to the session in WSResponse
.
I need it in order to use the key,value pair in subsequent WSRequests.
Can someone explain why this is the case and if there is a way to recover this?
(It would be great if someone can point me to the link where this(the result -> WSResponse conversion) is explained)
I thought of parsing the WSRequest
as Result
, but I am not sure if it'll recover the lost field.
A bit of explanation of what's under the hood
Between your client and your server, there's only plain standard HTTP requests and responses, there's no Play objects.
When the server returns a Result
, this result is transformed by Play HTTP server to a HTTP standard response.
In your client code, the WSResponse
is kinda the opposite: the client library received a standard HTTP response and transformed it in a WSResponse
for you to manipulate it as a Scala class.
Result
and WSResponse
somehow represent the same thing but in two different context (server vs. client). There's no reason to try to convert one into the other.
Back to your question, your server endpoint returns the following HTTP response:
Ok(...)
: code 200 (OK)"Done"
: body in plain text (without the quotes) as you didn't specify JSON or something elseaddingToSession("Key" -> "Value")
which as the name suggest use a Play server specific behaviour where some data are added to a "session" object that is sent back on each subsequent request and that the server may read to provide a response.In the standard HTTP response, there's no such thing as a session. The session data is actually stored in a cookie named SESSION
(by default) which itself is set through the HTTP response special header Set-Cookie: ...
.
What does it mean for your client code? It means that if you want to read this key-value, you need to retrieve the cookie from the WSResponse
and then parse it and extract the data.
Now, there are several issues with this approach:
What you probably want instead:
Return the key-value information in the body of the HTTP response, for instance in JSON:
Ok(Json.toJson(Map("key" -> "value")))
And in your client code:
val map = wsResponse.body.as[Map[String, String]]
map.get("key")
Another option, if for some reason you don't want to use the response body, would be to use HTTP headers. Headers are key-value that you can set on the server response and easily read on the client response.
Edit: I hadn't read the part where you say you need to send back the key-value on subsequent requests.
If you actually are not interested in the key-value excepted to send it back in subsequent requests, thus using the session can make sense and you only need to retrieve the cookie in the response and add it back to next request:
val sessionCookie = wsResponse.cookies.get("SESSION")
// Next request
wsRequest.addCookie(sessionCooKie).get
(Method names are approximative, check the documentation or your IDE will help)
Still, IMHO, using Play's session mechanism for this is not ideal. Depending on your exact use case (authentication?), I would implement something dedicated to it.