scala - Akka: How to wrap a message content into an HTTP response? -
in akka-http route specific message , want wrap content error message like:
val response:future[t] = (actor ? command).mapto[t] response match { case err : future[invalidrequest] => httpresponse(408, entity = err.map(_.tojson).????) case r : future[t] => r.map(_.tojson) } case class invalidrequest(error:string) implicit val invalidrequestformat = jsonformat1(invalidrequest)
but doesn't work. how can map text in json format?
i think can provide generic solution trying do. can start creating method returns route
follows:
def service[t:classtag](actor:actorref, command:any) (implicit timeout:timeout, _marshaller: toresponsemarshaller[t]):route = { val fut = (actor ? command).mapto[serviceresponse] oncomplete(fut){ case util.success(ir:invalidrequest) => complete(statuscodes.badrequest, ir) case util.success(t:t) => complete(t) case util.failure(ex) => complete(statuscodes.internalservererror ) } }
this method fires request supplied actor, via ask, , gets future
representing result. uses oncomplete
directive apply special handling invalidresponse
case. it's important here have implicit toresponsemarshaller[t]
in scope need success case.
then, let's had following classes , formatters defined:
trait serviceresponse case class foo(id:int) extends serviceresponse implicit val fooformat = jsonformat1(foo) case class invalidrequest(error:string) extends serviceresponse implicit val invalidrequestformat = jsonformat1(invalidrequest)
you use new service
method within routing tree follows:
val routes:route = { path("api" / "foo"){ get{ service[foo](fooactor, fooactor.dofoo) } } }
the problem example not waiting completion of future
before building out response. trying match on underlying type of future
, eliminated erasure @ runtime, not idea try , match against in way. instead need wait until it's completed , see type behind future
.
Comments
Post a Comment