给定 Future,http4s 可以执行不同的状态代码吗?
Can http4s do different status codes given a Future?
我正在使用 http4s,我有一个 Try
可以生成一些 json 响应数据:
case GET -> Root / "something" =>
getSomethingTry() match {
case Success(something) => Ok(something)
case Failure(CustomNotFoundException(reason)) => NotFound(reason)
case Failure(CustomConflictException()) => Conflict()
}
这个函数正确returns一个Task[Response]
但是,我想用 Future
替换 Try
。匹配不再有效,因为未来可能在匹配时尚未解决。所以,我可以描绘未来:
case GET -> Root / "something" =>
getSomethingFuture().map {
something => Ok(something)
}.recover {
case CustomNotFoundException(reason) => NotFound(reason)
case CustomConflictException() => Conflict()
}
但是这个 returns 一个 Future[Task[Response]]
这不是 http4s 想要的。使用 Await.result
拆箱 Future
似乎不合适 - 我认为这可能会导致线程池问题 - 但它确实使代码工作。
http4s 接受 futures 作为任务创建者的参数:
case GET -> Root / "something" =>
Ok(getSomethingFuture())
但这并不能让我在出现不同的错误时设置不同的状态码。解决方案可能是对任务执行 .recover
,但我看不到明显的方法。
如何在不同的 Future
失败情况下调用不同的 http4s 任务包装器?我需要使用中间件吗?
假设您使用的是 http4s
0.17 及更高版本,您的 Task
是 fs2.Task
。
很容易将Future
转换为Task
,然后处理后者:
case GET -> Root / "something" =>
Task.fromFuture(getSomethingFuture())
.flatMap {
something => Ok(something)
}
.handleWith {
case CustomNotFoundException(reason) => NotFound(reason)
case CustomConflictException() => Conflict()
}
不过,我建议在整个程序中使用 Task
而不是 Try
或 Future
你真的不需要打开未来的包装。 Play 框架提供 action.async 用于返回 Future.
您可以通过以下方式使用
Action.async {
getSomethingFuture().map {
something => Ok(something)
}.recover {
case CustomNotFoundException(reason) => NotFound(reason)
case CustomConflictException() => Conflict()
}
}
https://www.playframework.com/documentation/2.6.x/ScalaAsync#returning-futures
我正在使用 http4s,我有一个 Try
可以生成一些 json 响应数据:
case GET -> Root / "something" =>
getSomethingTry() match {
case Success(something) => Ok(something)
case Failure(CustomNotFoundException(reason)) => NotFound(reason)
case Failure(CustomConflictException()) => Conflict()
}
这个函数正确returns一个Task[Response]
但是,我想用 Future
替换 Try
。匹配不再有效,因为未来可能在匹配时尚未解决。所以,我可以描绘未来:
case GET -> Root / "something" =>
getSomethingFuture().map {
something => Ok(something)
}.recover {
case CustomNotFoundException(reason) => NotFound(reason)
case CustomConflictException() => Conflict()
}
但是这个 returns 一个 Future[Task[Response]]
这不是 http4s 想要的。使用 Await.result
拆箱 Future
似乎不合适 - 我认为这可能会导致线程池问题 - 但它确实使代码工作。
http4s 接受 futures 作为任务创建者的参数:
case GET -> Root / "something" =>
Ok(getSomethingFuture())
但这并不能让我在出现不同的错误时设置不同的状态码。解决方案可能是对任务执行 .recover
,但我看不到明显的方法。
如何在不同的 Future
失败情况下调用不同的 http4s 任务包装器?我需要使用中间件吗?
假设您使用的是 http4s
0.17 及更高版本,您的 Task
是 fs2.Task
。
很容易将Future
转换为Task
,然后处理后者:
case GET -> Root / "something" =>
Task.fromFuture(getSomethingFuture())
.flatMap {
something => Ok(something)
}
.handleWith {
case CustomNotFoundException(reason) => NotFound(reason)
case CustomConflictException() => Conflict()
}
不过,我建议在整个程序中使用 Task
而不是 Try
或 Future
你真的不需要打开未来的包装。 Play 框架提供 action.async 用于返回 Future.
您可以通过以下方式使用
Action.async {
getSomethingFuture().map {
something => Ok(something)
}.recover {
case CustomNotFoundException(reason) => NotFound(reason)
case CustomConflictException() => Conflict()
}
}
https://www.playframework.com/documentation/2.6.x/ScalaAsync#returning-futures