此图显示了如何创建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
?
答案 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)