10

本教程展示了如何创建 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.JsonEntityBody. 我见过的大多数示例都使用EntityEncoder,它不提供所需的类型。

我怎样才能转换io.circe.Json成一个EntityBody

4

2 回答 2

12

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实例,因此您关于不想使用 an 的评论EntityEncoder没有意义 -如果您不想自己创建字节流,则必须使用一个但是,http4s 库已经为许多类型预定义了一些类型,其中一个类型Json存在于org.http4s.circe._. 因此导入声明。

最后,您需要在.unsafeRunSync()此处调用以提取Request对象,因为withBody返回一个IO[Request[IO]]. 处理此问题的更好方法当然是将结果与其他IO操作链接起来。

于 2018-04-10T08:41:29.543 回答
9

从 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)
于 2019-04-25T23:00:27.680 回答