scala - Akka:如何将消息内容包装到 HTTP 响应中?

标签 scala akka akka-http

在我的 Akka-http 路由中,我收到一条特定的消息,我想将其内容包装为错误消息,例如:

val response:Future[T] = (actor ? command).mapTo[T]
    response match {
      case err : Future[InvalidRequest] => 
          HttpResponse(408, entity = err.map(_.toJson).????)
      case r : Future[T] => r.map(_.toJson)
    }

case class InvalidRequest(error:String)

implicit val invalidRequestFormat = jsonFormat1(InvalidRequest)

但这不起作用。如何将其映射为 json 格式的文本?

最佳答案

我想我可以为您想要做的事情提供一个通用的解决方案。您可以首先创建一个返回 Route 的方法,如下所示:

def service[T:ClassTag](actor:ActorRef, command:Any)
 (implicit timeout:Timeout,  _marshaller: ToResponseMarshaller[T]):Route = {
  val fut = (actor ? command).mapTo[ServiceResponse]
  onComplete(fut){
    case util.Success(ir:InvalidRequest) =>
      complete(StatusCodes.BadRequest, ir)

    case util.Success(t:T) =>
      complete(t)

    case util.Failure(ex) =>
      complete(StatusCodes.InternalServerError )        
  }    
}

此方法通过询问向提供的参与者发出请求,并获取代表结果的Future。然后,它使用 onComplete 指令对 InvalidResponse 情况应用特殊处理。这里重要的是,您在范围内有一个隐式的 ToResponseMarshaller[T] ,因为您将在成功案例中需要它。

然后,假设您定义了以下类和格式化程序:

trait ServiceResponse
case class Foo(id:Int) extends ServiceResponse
implicit val fooFormat = jsonFormat1(Foo)
case class InvalidRequest(error:String) extends ServiceResponse
implicit val invalidRequestFormat = jsonFormat1(InvalidRequest)

您可以在路由树中使用新的 service 方法,如下所示:

val routes:Route = {
  path("api" / "foo"){
    get{
      service[Foo](fooActor, FooActor.DoFoo)
    }
  }  
}

您的示例的问题在于您在构建响应之前没有等待 Future 完成。您试图匹配 Future 的基础类型,该类型会在运行时通过删除来消除,因此尝试以这种方式进行匹配并不是一个好主意。相反,您需要等到它完成,然后查看 Future 后面的类型。

关于scala - Akka:如何将消息内容包装到 HTTP 响应中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38328076/

相关文章:

Scala 修饰符和类型参数化

scala - 登录 Akka 时如何缩写 ActorRef 的路径?

java - akka 2.6 中的 TypedActors

scala - 是否可以在 akka.http.javadsl.server.Route 和 akka.http.scaladsl.server.Route 之间进行转换

scala - Akka Stream + Akka Http - 获取错误请求

scala - 如何用 Akka-Http 一般包装拒绝

scala - 如何在运行时为 docker 容器提供端口号?

java - postStop() 方法以防 actor 失败

json - 如何在 akka-http 中编码和解码 mongo ObjectId

json - Play Map[Int,_] 的 JSON 格式化程序