选项结果在akka-http中

时间:2016-08-19 04:29:14

标签: akka-http

尝试从aka-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 {

非常感谢任何帮助。

2 个答案:

答案 0 :(得分: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))
    }
  }
}

此代码现在处理来自Future的3个可能结果(Some成功,None成功和失败),每个产生Route那些案件。这应该可以解决你的问题。

答案 1 :(得分:0)

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

Future[Option[T]]

假设pathPrefix("contacts" / Segment) { id => get { complete(contactService.getById(id).map(toResource)) } } 返回一个类型,其中该函数返回的类型存在toResource。 Akka为ToEntityMarshallerFuture提供机制,因此您只需要提供Option部分。例如,如果您返回json并使用spray-json,那么您可以定义TJsonWriter[T]中的含义将完成剩下的工作。请参阅spray-json-support

实际上可能并不需要akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport,但是我假设它会将map(toResource)转换为其他类型的其他类型 - 如果它只是将其转换为json或类似的那么你可以删除它使用上面描述的内置编组支持。