I'm trying to create a Post request path using the Akka HTTP Server and the Scala programming language.
But after I successfully make the request, I find it difficult to access the values of the request body parameters.
I would like to access the values of parameters h
, w
of Impression and domain
of Site.
What is the best way to access these parameters?
I am using SprayJSON
as the marshaller.
The current code val h =bid_request_params.imp.h
gives the error value h is not a member of Option[List[com.example.WebServer.Impression]]
.
Again, the request is processed successfully, I just can't figure out how to access the values of the parameters.
The code is as below.
The case classes:
case class Site(id: String, domain: String)
case class Impression(id: String, h: Int, w: Int)
case class MyRequest(id: String, imp: Option[List[Impression]], site: Site)
The Post Request path:
path("submit") {
post {
entity(as[MyRequest]) { bid_request_params =>
val h = bid_request_params.imp.h
val w = bid_request_params.imp.w
val w = bid_request_params.site.domain
}
}
}
The request body:
{
"id": "SGu1Jpq1IO",
"site": {
"id": "0006a522f",
"domain": "btmn.tld"
},
"imp": [{
"id": "1",
"h": 250,
"w": 300
}]
}
The problem you have, is how you are trying to access the value of the imp
field of type Option[List[Impression]]
.
Based on how you defined your case classes, you would have something like this if you try to manually create an instance of MyRequest
case class Site(id: String, domain: String)
case class Impression(id: String, h: Int, w: Int)
case class MyRequest(id: String, imp: Option[List[Impression]], site: Site)
val request = MyRequest(
id = "SGu1Jpq1IO",
site = Site(
id = "0006a522f",
domain = "btmn.tld"
),
imp = Some( // here you have an Option
List( // here you have the List
Impression( // here is the Impression class you define
id = "1",
h = 250,
w = 300
)
)
)
)
when you try to do something like
val h = request // MyRequest
.imp // this field is of type Option[List[Impression]], not just Impression
.h // can't solve this because of the previous line
val w = request.imp.w
val w = request.site.domain
An Option
is a class that lets you work with the concept of a present or non-present value. To You need to use the methods provided by this class. Mostly map
, flatMap
, filter
but there are others such as fold
, getOrEsle
, orElse
or even you can use a for yield
or pattern matching
.
The same happens with the List
, where you can't access directly to the field of the element without using the methods that lets you traverse the collection and do something with the value contained by the list.
That being said, not sure if you need to redefine the schema of your payload, or you need to adapt the code to do something with the value received in the endpoint.
Here you have some examples of code
bid_request_params.imp match {
case Some(imps) => // in case the list was sent in the payload and is not null
for {
imp <- imps
} yield imp.h + imp.w // just doing a sum that probably doesn't make sense. Just to show that at this point I have access to the fields and this will return a new List
case None => // the list was not sent in the payload
}
// the following example should do the same of the code above but written in different way
bid_request_params
.imp // this is an Option
.map(imps => // the method from Option that lets me apply some transformation of the value contained, in this case the List
imps
.map(imp => // the method from List that lets me apply some transformation of each element of the List, in this case the Impressions
imp.h + imp.w // again the non-sense sum of the fields
)
)