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
bodyon 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 thewithBodymethod instead.withBodytakes an implicitEntityEncoderinstance, so your comment about not wanting to use anEntityEncoderdoesn'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 typeJsonlives inorg.http4s.circe._. Hence the import statement.Lastly, you need to call
.unsafeRunSync()here to pull out aRequestobject becausewithBodyreturns anIO[Request[IO]]. The better way to handle this would of course be via chaining the result with otherIOoperations.