JSON Processing
uni includes a pure Scala JSON parser with a convenient DSL for querying and manipulating JSON data.
Parsing JSON
scala
import wvlet.uni.json.JSON
val jsonString = """
{
"user": {
"id": 123,
"name": "Alice",
"email": "alice@example.com"
},
"posts": [
{"id": 1, "title": "Hello World"},
{"id": 2, "title": "Scala Tips"}
]
}
"""
val json = JSON.parse(jsonString)Extracting Values
Direct Access
scala
// Access nested values
val userId = json("user")("id").toLongValue // 123
val userName = json("user")("name").toStringValue // "Alice"
// Access array elements
val firstPost = json("posts")(0)("title").toStringValue // "Hello World"Path Navigation
Use / for path-based navigation:
scala
val email = (json / "user" / "email").toStringValue
// "alice@example.com"
// Navigate into arrays
val titles = (json / "posts" / "title").values
// Seq("Hello World", "Scala Tips")Safe Access with Option
scala
val email: Option[String] = for
user <- json.get("user")
email <- user.get("email")
yield email.toStringValueValue Types
JSON values have specific types:
scala
json match
case JSONObject(map) => // Object with fields
case JSONArray(items) => // Array of values
case JSONString(s) => // String value
case JSONLong(n) => // Integer value
case JSONDouble(d) => // Floating point
case JSONBoolean(b) => // Boolean
case JSONNull => // Null valueCreating JSON
Programmatic Construction
scala
import wvlet.uni.json.*
val userJson = JSONObject(Seq(
"id" -> JSONLong(456),
"name" -> JSONString("Bob"),
"active" -> JSONBoolean(true),
"scores" -> JSONArray(IndexedSeq(
JSONLong(95),
JSONLong(87),
JSONLong(92)
))
))Converting to String
scala
val jsonStr = userJson.toJSON
// {"id":456,"name":"Bob","active":true,"scores":[95,87,92]}Working with Arrays
scala
val posts = json("posts")
// Get all items
val allPosts = posts.values
// Map over items
val titles = posts.values.map(p => p("title").toStringValue)
// Filter items
val filteredPosts = posts.values.filter(p =>
p("id").toLongValue > 1
)Error Handling
JSON parsing can fail:
scala
try
val json = JSON.parse(invalidJson)
catch
case e: JSONParseException =>
println(s"Parse error: ${e.getMessage}")Safe parsing with Try:
scala
import scala.util.Try
val result = Try(JSON.parse(maybeInvalidJson))
result match
case scala.util.Success(json) => // Use json
case scala.util.Failure(e) => // Handle parse failureYAML Output
Convert JSON to YAML format:
scala
import wvlet.uni.json.YAMLFormatter
val yaml = YAMLFormatter.toYAML(json)
// user:
// id: 123
// name: Alice
// email: alice@example.comBest Practices
- Use path navigation for nested access
- Handle missing keys with
getorOption - Validate structure before deep traversal
- Use pattern matching for type-safe extraction
