Добавить json body в http4s Запрос
Этот раздел показывает, как создать запрос http4s: https://http4s.org/v0.18/dsl/.
Я хотел бы изменить этот запрос на метод POST и добавить литеральное тело json, используя circe. Я попробовал следующий код:
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
?
1 ответ
Ссылка Олега в основном покрывает это, но вот как бы вы сделали это для настраиваемого тела запроса:
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
операции.
Начиная с 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)