尝试从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 {
非常感谢任何帮助。
答案 0 :(得分:0)
您在此处看到的问题与您使用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
那些案件。这应该可以解决你的问题。
答案 1 :(得分:0)
@cmbaxter的答案是正确的,但如果您对上述三种情况的标准状态代码感到满意(Ok,NotFound,InternalServerError),那么您可以简化代码,直接使用返回{{1}的函数完成}。
Future[Option[T]]
假设pathPrefix("contacts" / Segment) { id =>
get {
complete(contactService.getById(id).map(toResource))
}
}
返回一个类型,其中该函数返回的类型存在toResource
。 Akka为ToEntityMarshaller
和Future
提供机制,因此您只需要提供Option
部分。例如,如果您返回json并使用spray-json,那么您可以定义T
,JsonWriter[T]
中的含义将完成剩下的工作。请参阅spray-json-support。
实际上可能并不需要akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
,但是我假设它会将map(toResource)
转换为其他类型的其他类型 - 如果它只是将其转换为json或类似的那么你可以删除它使用上面描述的内置编组支持。