Skip to content

scalapb-json/scalapb-circe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

bafd347 · Mar 17, 2025
Mar 3, 2025
Jun 29, 2024
Jan 13, 2025
Mar 17, 2025
Mar 3, 2023
Jan 13, 2025
Feb 7, 2021
Sep 23, 2022
Mar 12, 2025
Jan 3, 2018
Jul 1, 2024
Mar 16, 2025
Jul 1, 2024

Repository files navigation

scalapb-circe

scaladoc The structure of this project is hugely inspired by scalapb-json4s

Dependency

Include in your build.sbt file

core

libraryDependencies += "io.github.scalapb-json" %% "scalapb-circe" % "0.16.0"

for scala-js or scala-native

libraryDependencies += "io.github.scalapb-json" %%% "scalapb-circe" % "0.16.0"

macros

libraryDependencies += "io.github.scalapb-json" %% "scalapb-circe-macros" % "0.16.0"

Usage

JsonFormat

There are four functions you can use directly to serialize/deserialize your messages:

JsonFormat.toJsonString(msg) // returns String
JsonFormat.toJson(msg) // returns Json

JsonFormat.fromJsonString(str) // return MessageType
JsonFormat.fromJson(json) // return MessageType

Implicit Circe Codecs

You can also import codecs to support Circe's implicit syntax for objects of type GeneratedMessage and GeneratedEnum.

Assume a proto message:

message Guitar {
  int32 number_of_strings = 1;
}
import io.circe.syntax._
import io.circe.parser._
import scalapb_circe.codec._

Guitar(42).asJson.noSpaces // returns {"numberOfStrings":42}

decode[Guitar]("""{"numberOfStrings": 42}""") // returns Right(Guitar(42))
Json.obj("numberOfStrings" -> Json.fromInt(42)).as[Guitar] // returns Right(Guitar(42))

You can define an implicit scalapb_circe.Printer and/or scalapb_circe.Parser to control printing and parsing settings. For example, to include default values in Json:

import io.circe.syntax._
import io.circe.parser._
import scalapb_circe.codec._
import scalapb_circe.Printer

implicit val p: Printer = new Printer(includingDefaultValueFields = true)

Guitar(0).asJson.noSpaces // returns {"numberOfStrings": 0}

Finally, you can include scalapb GeneratedMessage and GeneratedEnums in regular case classes with semi-auto derivation:

import io.circe.generic.semiauto._
import io.circe.syntax._
import io.circe._
import scalapb_circe.codec._ // IntelliJ might say this is unused.

case class Band(guitars: Seq[Guitar])
object Band {
  implicit val dec: Decoder[Band] = deriveDecoder[Band]
  implicit val enc: Encoder[Band] = deriveEncoder[Band]
}
Band(Seq(Guitar(42))).asJson.noSpaces // returns {"guitars":[{"numberOfStrings":42}]}

Credits

Contributors 8

Languages