当我试图从aka-http返回一个选项结果时遇到了一个问题。
基本上它是一个get,可能有一个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 {任何帮助都将不胜感激。
发布于 2016-08-21 21:28:14
您在这里看到的问题与您使用Future的事实有关,而不是因为Option。我将假设调用contactService.getById(id)返回一个Future。由于您的路由树中的任何路由都需要是Route (RequestContext => 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。这应该可以解决您的问题。
发布于 2016-08-23 07:18:40
@cmbaxter的答案是正确的,但如果你对上面三种情况(Ok,NotFound,InternalServerError)的标准状态码满意,那么你可以简化代码,直接完成返回Future[Option[T]]的函数。
pathPrefix("contacts" / Segment) { id =>
get {
complete(contactService.getById(id).map(toResource))
}
}也就是说,假设toResource返回一个类型,其中该函数返回的类型存在ToEntityMarshaller。Akka提供了用于Future和Option的机制,因此您只需要提供T部分。例如,如果您返回json并使用example json,那么您可以定义一个JsonWriter[T],而akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport中的隐式将完成剩下的工作。参见spray-json-support。
map(toResource)实际上可能不是必需的,但我假设它会将ContactDto转换为其他类型-如果只是将其转换为json或类似类型,那么您可以删除它,并使用如上所述的内置编组支持。
https://stackoverflow.com/questions/39031134
复制相似问题