druvu-lib-json
Build JSON fluently, parse it strictly — over Gson or Jackson, and the same API over YAML.
Numbers stay exact, nothing is coerced, and every error says where it happened. Published to GitHub Packages, which needs a one-time token to read — see Install.
Try it
Building:
String json = Json.object()
.add("prop1", "1")
.add("prop2", 2)
.addObject("prop5").add("np1", 4).end()
.addArray("prop6").add("ae1").add("ae2").end()
.toJson();
// {"prop1":"1","prop2":2,"prop5":{"np1":4},"prop6":["ae1","ae2"]}
Nesting with a body — no end() to misplace:
String json = Json.object()
.add("jsonrpc", "2.0")
.addObject("error", e -> e.add("code", -32601).add("message", "Method not found"))
.toJson();
Parsing:
JsonObject root = Json.parse(payload).asObject();
String id = root.string("id");
boolean active = root.bool("active");
BigDecimal total = root.decimal("total");
long sequence = root.longValue("sequence");
for (JsonValue item : root.array("items")) {
JsonObject o = item.asObject();
// ...
}
YAML, same tree, different front door:
String config = Yaml.object()
.add("endpoint", url)
.addArray("profiles").add("sandbox").add("prod").end()
.toJson();
JsonObject parsed = Yaml.parse(config).asObject();
What you get
- one API, your choice of engine:
druvu-lib-json-gson,druvu-lib-json-jackson(Jackson 3) ordruvu-lib-json-yaml(YAML 1.2). The backend is discovered on the class path; your application brings its own Gson or Jackson version. - strict accessors. Asking a string for a number throws, with the path:
Expected NUMBER but found STRING at $.items[0].name. A missing key lists the keys that are there. - numbers as
BigDecimal, exactly as they came off the wire.asInt()andasLong()succeed only when exact. There is nodoubleaccessor. - a
nullon the wire reads as “not given”:find(key)is empty for a missing key and for a null one. The write side refusesnull. Omit what you do not have. - strict RFC 8259 parsing, and a sealed value hierarchy that pattern-matches exhaustively.
build()returns whatparsereturns, so a built tree is navigable without serializing, and a parsed fragment grafts into a builder.- three ways to write (since 1.1.0): the chain for flat shapes, a lambda body for deeper or conditional nesting, and
Json.fill— the JSON itself with?placeholders, bound in order, each value serialized by the backend, then parsed strictly. Optional members read typed:findString(key)and friends return anOptional,string(key, fallback)answers absence. - YAML 1.2 core schema only:
yesis a string,1:30is a string,1_000is a string. YAML is chosen at the call site, not discovered, so it sits next to a JSON backend without shadowing it.
What it refuses
- two JSON backends on one class path — discovery fails, naming both
- values and builders from different backends mixed together
- malformed documents, trailing content, single quotes, unquoted keys
- YAML 1.1 spellings, mapping keys that are not scalars, and
.infor.nanread as a number
Install (GitHub Packages)
GitHub Packages needs Maven authentication even for a public package. Once per machine: a classic token with the single read:packages scope
(this link pre-selects it; fine-grained tokens are refused with an unexplained 401), and a server entry in ~/.m2/settings.xml:
<servers>
<server>
<id>github</id>
<username>YOUR_GITHUB_USERNAME</username>
<password>YOUR_GITHUB_TOKEN</password>
</server>
</servers>
Then in the project, the repository and one backend. The api comes with it.
<repositories>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/DenissLarka/druvu-lib-json</url>
</repository>
</repositories>
<dependency>
<groupId>com.druvu</groupId>
<artifactId>druvu-lib-json-gson</artifactId>
<version>1.1.0</version>
</dependency>
<!-- or druvu-lib-json-jackson, or druvu-lib-json-yaml -->
Java 25 or newer. Writing a backend of your own: the contract suite ships as the api’s tests artifact, and the README has the steps.
Where it comes from
The builder DSL began as Bryn Cooke’s fluent-json. This library detached it from Gson behind a small backend SPI and added the parsing side.
Something it almost does?
Open an issue, or write to me. If it is small and useful to more than you, I will often just build it.
Apache License 2.0. Original fluent-json Copyright 2013 Bryn Cooke.