scalaintermediate
JSON Parsing with Circe
Parse and generate JSON with Circe: codecs, custom encoders/decoders, and optics.
scalaPress ⌘/Ctrl + Shift + C to copy
import io.circe.*
import io.circe.syntax.*
import io.circe.parser.*
import io.circe.generic.auto.*
case class Address(street: String, city: String, zip: String)
case class User(name: String, age: Int, email: String, address: Address)
case class ApiResponse[T](data: T, status: Int, message: String)
@main def run(): Unit =
// Encoding
val user = User("Alice", 30, "alice@test.com", Address("123 Main", "NYC", "10001"))
val json = user.asJson
println(json.spaces2)
// Decoding
val jsonString = """
|{
| "name": "Bob",
| "age": 25,
| "email": "bob@test.com",
| "address": {
| "street": "456 Oak Ave",
| "city": "LA",
| "zip": "90001"
| }
|}
""".stripMargin
decode[User](jsonString) match
case Right(user) => println(s"Parsed: $user")
case Left(error) => println(s"Error: $error")
// Manual cursor navigation
val doc = parse(jsonString).getOrElse(Json.Null)
val cursor = doc.hcursor
val name = cursor.downField("name").as[String]
val city = cursor.downField("address").downField("city").as[String]
println(s"Name: $name, City: $city")
// Modify JSON
val modified = cursor
.downField("age")
.withFocus(_.mapNumber(n => Json.fromInt(n.toInt.getOrElse(0) + 1).asNumber.get))
.top
println(s"Modified: ${modified.map(_.spaces2)}")
// Custom encoder/decoder
case class Money(cents: Long)
given Encoder[Money] = Encoder.instance { m =>
Json.obj("amount" -> Json.fromDoubleOrNull(m.cents / 100.0), "currency" -> Json.fromString("USD"))
}
given Decoder[Money] = Decoder.instance { c =>
for
amount <- c.downField("amount").as[Double]
yield Money((amount * 100).toLong)
}
println(Money(4999).asJson.noSpaces)
println(decode[Money]("""{"amount":49.99,"currency":"USD"}"""))
// List encoding
val users = List(
User("Alice", 30, "a@t.com", Address("1 St", "NYC", "10001")),
User("Bob", 25, "b@t.com", Address("2 Ave", "LA", "90001"))
)
println(users.asJson.spaces2)
// API response
val response = ApiResponse(users, 200, "OK")
println(response.asJson.spaces2)Use Cases
- REST API JSON handling
- Configuration file parsing
- Data serialization and deserialization
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
scalaintermediate
Advanced JSON with Circe
Handle complex JSON with Circe: custom codecs, optics, cursor navigation, and error handling.
Best for: API response parsing
#scala#circe
scalaintermediate
XML Processing and Parsing
Parse and generate XML in Scala: literals, pattern matching, XPath-like queries, and transformation.
Best for: XML configuration parsing
#scala#xml
typescriptadvanced
JSON Stream Parser
Parses large JSON arrays from a readable stream without loading the entire file into memory.
Best for: Processing large log files
#streaming#json
scalabeginner
Scala Hello World Application
Create a basic Scala application with main method, string interpolation, and val/var basics.
Best for: Getting started with Scala
#scala#basics