How to use Circe - which imports to use, auto vs semiauto derivation, etc…
Circe Standalone#
Auto Derivation#
Auto derivation is typically used. Circe will using shapeless for derivation of types to determine how to encode and decode.
Semiauto Derivation#
Semiauto derivation is very similar to auto but allows for selecting whether to encode or just decode.
With http4s / cats-effect#
Auto Derivation#
//> using scala "3.2.2"
//> using dep "io.circe::circe-core:0.14.5"
//> using dep "io.circe::circe-generic:0.14.5"
//> using dep "io.circe::circe-parser:0.14.5"
//> using dep "org.http4s::http4s-circe:0.23.18"
//> using dep "org.http4s::http4s-dsl:0.23.18"
//> using dep "org.http4s::http4s-ember-client:0.23.18"
//> using dep "org.http4s::http4s-ember-server:0.23.18"
//> using dep "org.typelevel::cats-effect:3.4.10"
//> using dep "ch.qos.logback:logback-classic:1.4.7"
import cats.effect.*
import com.comcast.ip4s.*
import io.circe.*
import io.circe.syntax.*
import io.circe.generic.auto.*
import org.http4s.*
import org.http4s.circe.*
import org.http4s.dsl.io.*
import org.http4s.implicits.*
import org.http4s.ember.server.*
case class HelloResponse(greeting: String)
object Main extends IOApp {
val helloWorldService = HttpRoutes.of[IO] {
case GET -> Root / "hello" / name =>
Ok(HelloResponse(s"Hello, $name").asJson)
}.orNotFound
def run(args: List[String]): IO[ExitCode] =
EmberServerBuilder
.default[IO]
.withHost(ipv4"0.0.0.0")
.withPort(port"8080")
.withHttpApp(helloWorldService)
.build
.use(_ => IO.never)
.as(ExitCode.Success)
}
Semiauto Derivation#
//> using scala "3.2.2"
//> using dep "io.circe::circe-core:0.14.5"
//> using dep "io.circe::circe-generic:0.14.5"
//> using dep "io.circe::circe-parser:0.14.5"
//> using dep "org.http4s::http4s-circe:0.23.18"
//> using dep "org.http4s::http4s-dsl:0.23.18"
//> using dep "org.http4s::http4s-ember-client:0.23.18"
//> using dep "org.http4s::http4s-ember-server:0.23.18"
//> using dep "org.typelevel::cats-effect:3.4.10"
//> using dep "ch.qos.logback:logback-classic:1.4.7"
import cats.effect.*
import com.comcast.ip4s.*
import io.circe.*
import io.circe.syntax.*
import io.circe.generic.semiauto.*
import org.http4s.*
import org.http4s.circe.*
import org.http4s.dsl.io.*
import org.http4s.implicits.*
import org.http4s.ember.server.*
case class HelloResponse(greeting: String)
given Encoder[HelloResponse] = deriveEncoder
given Decoder[HelloResponse] = deriveDecoder
// Both decoder and encoder as a codec
// given Codec[HelloResponse] = deriveCodec[HelloResponse]
object Main extends IOApp {
val helloWorldService = HttpRoutes.of[IO] {
case GET -> Root / "hello" / name =>
Ok(HelloResponse(s"Hello, $name").asJson)
}.orNotFound
def run(args: List[String]): IO[ExitCode] =
EmberServerBuilder
.default[IO]
.withHost(ipv4"0.0.0.0")
.withPort(port"8080")
.withHttpApp(helloWorldService)
.build
.use(_ => IO.never)
.as(ExitCode.Success)
}