Is there an actual reason why you are implementing this with spray-can? In routing it's more easier and natural:
lazy val yourRoute: Route = {
(post & path("userAction")) {
entity(as[SomeType]) { data =>
// do what you want
}
}
}
In this version it all comes to the proper unmarshaller for your type (SomeType
). But if you want to stick with spray-can, you can use spray-httpx unmarshaller. I don't have IDE near to me, but this can like this (actual code from my project with some Scalaz tricks):
case request @ HttpRequest(...) =>
fromTryCatch(request.entity |> unmarshal[SomeType]) // returns Throwable \/ SomeType, like scala's Either type
Here it also comes to the right unmarshaller, e.g if you want to get your entity in Json format (i.e spray JsObject), then you need to emit a request with json payload, write entity(as[JsObject])
and provide an implicit unmarshaller from spray.json.SprayJsonSupport
. I think that using this approach for FormData
is a bit overhead, cause for simple Post payload you have formFields
directive, and you can write:
lazy val yourRoute: Route = {
(post & path("userAction")) {
formFields(...) { fields => // just enumerate field names from your FormData
// do what you want
}
}
}
For Map approach if the same, just add spray.json.DefaultJsonProtocol
into the scope, to add unmarshaller for maps.
Still using spray-routing DSL is far better then dealing with low-level can code. If you still want to use, then take a look at spray.httpx.unmarshalling
package, it contains different types of unmarshallers, for entity, request and response.