如何根据未来结果在喷涂路由中设置状态代码和标头

时间:2015-06-15 22:38:42

标签: spray

我正在使用Akka的喷射路由来定义像

这样的路线
def items = path("items") {
  get {
    complete {
      actor.ask(GetItems)(requestTimeout).mapTo[Either[NoChange, Items]] map {
         result => result match {
            case Left(_) => StatusCodes.NotModified
            case Right(items) => 
               // here I want to set an HTTP Response header based on a 
               // field within items -- items.revision
               items
         }
      }
    }
  }
}

actor.ask返回一个映射到Future的Future [[NoChange,Items]]。 “complete”很乐意处理Future [StatusCodes ...]或Future [Items],但我不确定如何在Future中设置HTTP Response头。

如果未在Future中设置标题,那么我可以将整数包装在指令中,但如何在完整内设置标题?

我正在使用Spray 1.2.0。

感谢您指出正确的方向!

1 个答案:

答案 0 :(得分:2)

如果您尝试在complete内部执行此操作,则内​​部表达式的所有分支都必须生成可由complete编组的类型。

您可以尝试使用这样的结构使其正常工作:

complete {
  actor.ask(GetItems)(requestTimeout).mapTo[Either[NoChange, Items]] map {
     result => result match {
        case Left(_) => StatusCodes.NotModified: ToResponseMarshallable
        case Right(items) => 
           // here I want to set an HTTP Response header based on a 
           // field within items -- items.revision

           val headers = // items...
           HttpResponse(..., headers = headers): ToResponseMarshallable
     }
  }
}

这可以确保您传递给complete的表达式的类型为Future[ToResponseMarshallable],这应该始终是可编组的。

更好的方法是使用onSuccess directive,让你在未来完成后使用其他指令:

get {
  def getResult() = actor.ask(GetItems)(requestTimeout).mapTo[Either[NoChange, Items]]
  onSuccess(getResult()) {
    case Left(_) => complete(StatusCodes.NotModified)
    case Right(items) => 
      // do whatever you want, e.g.
      val extraHeaders = // items.revisions
      respondWithHeaders(extraHeaders) {
        complete(...)
      }
  }
}