2016-08-19 50 views
1

我在尝试从aka-http返回选项结果时遇到问题。选项结果akka-http

基本上它可能有一个404

pathPrefix("contacts"/Segment) { id => 
    get { 
     contactService.getById(id).map { 
     case Some(c: ContactDto) => complete(OK -> toResource(c)) 
     case None => complete(HttpResponse(NotFound)) 
     } 
    } 
    } 

,给了我和错误得到:

[error] found : scala.concurrent.Future[akka.http.scaladsl.server.StandardRoute] 
[error] required: akka.http.scaladsl.server.Route 
[error]  (which expands to) akka.http.scaladsl.server.RequestContext => scala.concurrent.Future[akka.http.scaladsl.server.RouteResult] 
[error]  contactService.getById(id).map { 

任何帮助将不胜感激。

回答

0

您在这里看到的问题与您使用Future而不是因为Option的事实有关。我将假设电话contactService.getById(id)返回Future。由于您的路由树中的任何路由的结果必须是RouteRequestContext => Future[RouteResult]的简称),而您的Future本身不是Route,因此您需要稍作更改以处理这种情况。您应该能够使用onComplete指令配搭您Future如下:

pathPrefix("contacts"/Segment) { id => 
    get { 
    val fut = contactService.getById(id) 
    onComplete(fut){ 
     case util.Success(Some(c: ContactDto)) => 
     complete(OK -> toResource(c)) 
     case util.Success(None) => 
     complete(HttpResponse(NotFound)) 
     case util.Failure(ex) => 
     complete(HttpResponse(InternalServerError)) 
    } 
    } 
} 

此代码现在处理的3个可能的结果从Future(成功与Some,成功与None和失败),为每种情况产生Route。这应该可以解决你的问题。

0

@ cmbaxter的回答是正确的,但如果您对以上三种情况(Ok,NotFound,InternalServerError)的标准状态代码感到满意,那么您可以简化代码,直接使用返回Future[Option[T]]的函数直接完成。

pathPrefix("contacts"/Segment) { id => 
    get { 
    complete(contactService.getById(id).map(toResource)) 
    } 
} 

即假设toResource返回其中ToEntityMarshaller存在由函数返回的类型的类型。 Akka为FutureOption提供机器,因此您只需提供T零件。例如,如果您返回json并使用spray-json,那么您可以定义一个JsonWriter[T],而akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport中的含义将完成剩下的工作。见spray-json-support

map(toResource)实际上可能并不需要,但我假设做一些其他类型的ContactDto额外的转换 - 如果它只是将其转换为JSON或类似的,那么你可以删除它,并使用在内置编组支持如上所述。