J%

J% module

JSON

JSON documents with typed values spliced in, validated against a JSON Schema while you build and again when you render.

Base type
org.jmod.dsl.json.JsonObject
Configuration
JsonConfiguration

Write the document with placeholders where the values go. The compiler parses it while it builds, and you get a class whose constructor takes those values and whose toJson() renders the document — each value encoded properly, so nothing can break out of its position.

Writing one

package examples.simplejson;

import org.jmod.dsl.json.JsonObject;

public external Person extends JsonObject<JsonConf> {
{
  "name": #[name]<String>,
  "age": #[age]<int>,
  "tags": #[tags]<String[]>
}
}
String body = new Person("Ada", 36, tags).toJson();
JsonNode tree = new Person("Ada", 36, tags).toJsonNode();

Checking against a schema

Give the configuration a JSON Schema — JSONMOD_SCHEMA_AWARE and JSONMOD_SCHEMA_URI — and the document is validated twice: at build time against the types you declared, and again at toJson() against the actual values. Drafts 4 through 2020-12 are supported.

P.jmod: JSON Schema validation failed: $.age: string found, integer expected

P.jmod: JSON Schema validation failed: $: required property 'age' not found

The build-time pass proves the shape is right for the declared types; the runtime pass catches what only the values can violate — a negative age under minimum: 0, a string that fails a pattern — and throws rather than emitting a document that does not conform.

Worth knowing

Values can be booleans, numbers, strings or arrays of those; objects are not encoded reflectively. Placeholders go where a JSON value goes — not inside a string, and not as a key — and the structure is fixed when you compile, so there is no way to add or omit a field per instance.