将json正文添加到http4s请求

时间:2018-04-09 05:36:58

标签: scala http4s http4s-circe

此图显示了如何创建http4s请求:https://http4s.org/v0.18/dsl/#testing-the-service

我想将此请求更改为POST方法,并使用circe添加文字json正文。我尝试了以下代码:

val body = json"""{"hello":"world"}"""
val req = Request[IO](method = Method.POST, uri = Uri.uri("/"), body = body)

这给我一个类型不匹配错误:

[error]  found   : io.circe.Json
[error]  required: org.http4s.EntityBody[cats.effect.IO]
[error]     (which expands to)  fs2.Stream[cats.effect.IO,Byte]
[error]     val entity: EntityBody[IO] = body

我理解错误,但我无法弄清楚如何将io.circe.Json转换为EntityBody。我见过的大多数示例都使用了EntityEncoder,它没有提供所需的类型。

如何将io.circe.Json转换为EntityBody

2 个答案:

答案 0 :(得分:9)

Oleg的链接主要涵盖了它,但这里是你如何为自定义请求体做的:

import org.http4s.circe._

val body = json"""{"hello":"world"}"""
val req = Request[IO](method = Method.POST, uri = Uri.uri("/"))
  .withBody(body)
  .unsafeRunSync()

说明:

请求类中的参数body的类型为EntityBody[IO],它是Stream[IO, Byte]的别名。您不能直接为其分配String或Json对象,而是需要使用withBody方法。

withBody采用隐式EntityEncoder实例,因此您对不想使用EntityEncoder的评论没有意义 - 您拥有如果您不想自己创建字节流,请使用一个。但是,http4s库具有多种类型的预定义库,Json类型的库存在org.http4s.circe._中。因此导入声明。

最后,您需要在此处致电.unsafeRunSync()以提取Request对象,因为withBody会返回IO[Request[IO]]。处理此问题的更好方法当然是通过将结果与其他IO操作联系起来。

答案 1 :(得分:0)

从http4s 20.0开始,withEntity用新主体覆盖现有主体(默认为空)。 EntityEncoder仍然是必需的,可以通过导入org.http4s.circe._找到:

import org.http4s.circe._

val body = json"""{"hello":"world"}"""

val req = Request[IO](
  method = Method.POST,
  uri = Uri.uri("/")
)
.withEntity(body)