在 http4s 中发送 JSON 响应的正确方法是什么?
What is the right way to send JSON response in http4s?
不久前我从 akka-http 切换到 http4s。我想正确做的基本事情之一——JSON 处理,特别是发送 JSON 响应。
我决定将 http4s 与 ZIO 而不是 cat 一起使用,因此 http 路由如下所示:
import fs2.Stream
import org.http4s._
import org.http4s.dsl.io._
import org.http4s.implicits._
import scalaz.zio.Task
import scalaz.zio.interop.catz._
import io.circe.generic.auto._
import io.circe.syntax._
class TweetsRoutes {
case class Tweet(author: String, tweet: String)
val helloWorldService = HttpRoutes.of[Task] {
case GET -> Root / "hello" / name => Task {
Response[Task](Ok)
.withBodyStream(Stream.emits(
Tweet(name, "dummy tweet text").asJson.toString.getBytes
))
}
}.orNotFound
}
如您所见,JSON 序列化部分非常冗长:
.withBodyStream(Stream.emits(
Tweet(name, "dummy tweet text").asJson.toString.getBytes
))
是否有任何其他方式在响应中发送 JSON?
是的,有:为任务定义和编码器和解码器:
implicit def circeJsonDecoder[A](
implicit decoder: Decoder[A]
): EntityDecoder[Task, A] = jsonOf[Task, A]
implicit def circeJsonEncoder[A](
implicit encoder: Encoder[A]
): EntityEncoder[Task, A] = jsonEncoderOf[Task, A]
这样就不用转字节了
编辑:这里有一个完整的例子:https://github.com/mschuwalow/zio-todo-backend/blob/develop/src/main/scala/com/schuwalow/zio/todo/http/TodoService.scala
HT:@mschuwalow
对此还有更简单的解决方案。如果你想为 HTTP 响应处理 case class JSON 编码,你可以添加这些导入:
import io.circe.generic.auto._
import org.http4s.circe.CirceEntityCodec._
顺便说一句,相同的导入处理传入的 JSON 请求的解码到案例 classes 以及
不久前我从 akka-http 切换到 http4s。我想正确做的基本事情之一——JSON 处理,特别是发送 JSON 响应。
我决定将 http4s 与 ZIO 而不是 cat 一起使用,因此 http 路由如下所示:
import fs2.Stream
import org.http4s._
import org.http4s.dsl.io._
import org.http4s.implicits._
import scalaz.zio.Task
import scalaz.zio.interop.catz._
import io.circe.generic.auto._
import io.circe.syntax._
class TweetsRoutes {
case class Tweet(author: String, tweet: String)
val helloWorldService = HttpRoutes.of[Task] {
case GET -> Root / "hello" / name => Task {
Response[Task](Ok)
.withBodyStream(Stream.emits(
Tweet(name, "dummy tweet text").asJson.toString.getBytes
))
}
}.orNotFound
}
如您所见,JSON 序列化部分非常冗长:
.withBodyStream(Stream.emits(
Tweet(name, "dummy tweet text").asJson.toString.getBytes
))
是否有任何其他方式在响应中发送 JSON?
是的,有:为任务定义和编码器和解码器:
implicit def circeJsonDecoder[A](
implicit decoder: Decoder[A]
): EntityDecoder[Task, A] = jsonOf[Task, A]
implicit def circeJsonEncoder[A](
implicit encoder: Encoder[A]
): EntityEncoder[Task, A] = jsonEncoderOf[Task, A]
这样就不用转字节了
编辑:这里有一个完整的例子:https://github.com/mschuwalow/zio-todo-backend/blob/develop/src/main/scala/com/schuwalow/zio/todo/http/TodoService.scala
HT:@mschuwalow
对此还有更简单的解决方案。如果你想为 HTTP 响应处理 case class JSON 编码,你可以添加这些导入:
import io.circe.generic.auto._
import org.http4s.circe.CirceEntityCodec._
顺便说一句,相同的导入处理传入的 JSON 请求的解码到案例 classes 以及