This tut shows how to create an http4s Request: https://http4s.org/v0.18/dsl/#testing-the-service
I would like to change this request to a POST method and add a literal json body using circe. I tried the following code:
val body = json"""{"hello":"world"}"""
val req = Request[IO](method = Method.POST, uri = Uri.uri("/"), body = body)
This gives me a type mismatch error:
[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
I understand the error, but I cannot figure out how to convert io.circe.Json
into an EntityBody
. Most examples I have seen use an EntityEncoder
, which does not provide the required type.
How can I convert io.circe.Json
into an EntityBody
?
Oleg's link mostly covers it, but here's how you'd do it for a custom request body:
Explanation:
The parameter
body
on the request class is of typeEntityBody[IO]
which is an alias forStream[IO, Byte]
. You can't directly assign a String or Json object to it, you need to use thewithBody
method instead.withBody
takes an implicitEntityEncoder
instance, so your comment about not wanting to use anEntityEncoder
doesn't make sense - you have to use one if you don't want to create a byte stream yourself. However, the http4s library has predefined ones for a number of types, and the one for typeJson
lives inorg.http4s.circe._
. Hence the import statement.Lastly, you need to call
.unsafeRunSync()
here to pull out aRequest
object becausewithBody
returns anIO[Request[IO]]
. The better way to handle this would of course be via chaining the result with otherIO
operations.