Specification: Core | Import | Alternate Names | Symbols, Units, Currencies | Validation | Conditional Composition

JSON Structure

Logo

JSON Structure is a data structure definition language that enforces strict typing, modularity, and determinism.

View the Project on GitHub json-structure

JSON Structure SDK for Java

A Java SDK for working with JSON Structure schemas, providing:

Requirements

Installation

Add to your pom.xml:

<dependency>
    <groupId>org.json-structure</groupId>
    <artifactId>json-structure</artifactId>
    <version>${version}</version>
</dependency>

Replace ${version} with the desired version number.

Usage

Schema Validation

Validate that a JSON Structure schema is well-formed:

import org.json_structure.validation.SchemaValidator;
import org.json_structure.validation.ValidationResult;

SchemaValidator validator = new SchemaValidator();
String schema = """
    {
        "$schema": "https://json-structure.org/meta/core/v1.0",
        "type": "object",
        "properties": {
            "name": { "type": "string" },
            "age": { "type": "int32" }
        },
        "required": ["name"]
    }
    """;

ValidationResult result = validator.validate(schema);
if (result.isValid()) {
    System.out.println("Schema is valid!");
} else {
    result.getErrors().forEach(e -> System.out.println(e.getMessage()));
}

Instance Validation

Validate JSON data against a schema:

import org.json_structure.validation.InstanceValidator;
import org.json_structure.validation.ValidationResult;

InstanceValidator validator = new InstanceValidator();
String schema = """
    {
        "type": "object",
        "properties": {
            "name": { "type": "string" },
            "age": { "type": "int32", "minimum": 0 }
        },
        "required": ["name"]
    }
    """;

String instance = """
    {
        "name": "Alice",
        "age": 30
    }
    """;

ValidationResult result = validator.validate(instance, schema);
System.out.println("Valid: " + result.isValid());

Schema Export from Java Types

Generate JSON Structure schemas from Java classes:

import org.json_structure.schema.JsonStructureSchemaExporter;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Person {
    private String name;
    private int age;
    private LocalDate birthDate;
    
    // getters and setters
}

ObjectMapper mapper = new ObjectMapper();
JsonNode schema = JsonStructureSchemaExporter.getSchemaAsNode(Person.class, mapper);
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema));

Output:

{
    "$schema": "https://json-structure.org/meta/core/v1.0",
    "type": "object",
    "title": "Person",
    "properties": {
        "name": { "type": "string" },
        "age": { "type": "int32" },
        "birthDate": { "type": "date" }
    },
    "required": ["name", "age", "birthDate"]
}

Jackson Module for Extended Types

Register the JSON Structure module for extended type handling:

import org.json_structure.converters.JsonStructureModule;
import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JsonStructureModule());

// Supports extended numeric types like Int128, UInt128, Decimal, etc.

JVM Language Interoperability

The Java SDK can be used directly from other JVM languages without any wrapper code. The following examples demonstrate how to use the SDK from popular JVM languages.

Kotlin

Kotlin has 100% Java interoperability and is widely used for Android and backend development.

Dependency (Gradle Kotlin DSL)

dependencies {
    implementation("org.json-structure:json-structure:${version}")
}

Schema Validation Example

import org.json_structure.validation.SchemaValidator
import org.json_structure.validation.ValidationResult

fun main() {
    val validator = SchemaValidator()
    val schema = """
        {
            "type": "object",
            "properties": {
                "name": { "type": "string" },
                "age": { "type": "int32" }
            },
            "required": ["name"]
        }
    """
    
    val result: ValidationResult = validator.validate(schema)
    if (result.isValid()) {
        println("Schema is valid!")
    } else {
        result.getErrors().forEach { error -> 
            println(error.getMessage())
        }
    }
}

Instance Validation Example

import org.json_structure.validation.InstanceValidator
import org.json_structure.validation.ValidationResult

fun validateInstance() {
    val validator = InstanceValidator()
    val schema = """{"type": "string"}"""
    val instance = """"Hello, World!""""
    
    val result: ValidationResult = validator.validate(instance, schema)
    println("Valid: ${result.isValid()}")
}

Idiomatic Notes:

Scala

Scala provides full JVM interoperability and is popular in data engineering and functional programming.

Dependency (sbt)

libraryDependencies += "org.json-structure" % "json-structure" % "${version}"

Schema Validation Example

import org.json_structure.validation.{SchemaValidator, ValidationResult}
import scala.jdk.CollectionConverters._

object SchemaValidation extends App {
  val validator = new SchemaValidator()
  val schema = """{
    "type": "object",
    "properties": {
      "name": { "type": "string" },
      "age": { "type": "int32" }
    },
    "required": ["name"]
  }"""
  
  val result: ValidationResult = validator.validate(schema)
  if (result.isValid) {
    println("Schema is valid!")
  } else {
    result.getErrors.asScala.foreach(error => println(error.getMessage))
  }
}

Instance Validation Example

import org.json_structure.validation.{InstanceValidator, ValidationResult}

object InstanceValidation extends App {
  val validator = new InstanceValidator()
  val schema = """{"type": "string"}"""
  val instance = """"Hello, Scala!""""
  
  val result: ValidationResult = validator.validate(instance, schema)
  println(s"Valid: ${result.isValid}")
}

Idiomatic Notes:

Groovy

Groovy is a dynamic JVM language used extensively in Gradle and scripting.

Dependency (Gradle Groovy DSL)

dependencies {
    implementation 'org.json-structure:json-structure:${version}'
}

Schema Validation Example

import org.json_structure.validation.SchemaValidator
import org.json_structure.validation.ValidationResult

def validator = new SchemaValidator()
def schema = '''
{
    "type": "object",
    "properties": {
        "name": { "type": "string" },
        "age": { "type": "int32" }
    },
    "required": ["name"]
}
'''

ValidationResult result = validator.validate(schema)
if (result.isValid()) {
    println "Schema is valid!"
} else {
    result.getErrors().each { error ->
        println error.getMessage()
    }
}

Instance Validation Example

import org.json_structure.validation.InstanceValidator
import org.json_structure.validation.ValidationResult

def validator = new InstanceValidator()
def schema = '{"type": "string"}'
def instance = '"Hello, Groovy!"'

ValidationResult result = validator.validate(instance, schema)
println "Valid: ${result.isValid()}"

Idiomatic Notes:

Clojure

Clojure is a functional Lisp dialect on the JVM with direct Java interoperability.

Dependency (Leiningen)

:dependencies [[org.json-structure/json-structure "${version}"]]

Schema Validation Example

(ns myapp.validation
  (:import [org.json_structure.validation SchemaValidator ValidationResult]))

(defn validate-schema []
  (let [validator (SchemaValidator.)
        schema "{\"type\": \"object\",
                 \"properties\": {
                   \"name\": {\"type\": \"string\"},
                   \"age\": {\"type\": \"int32\"}
                 },
                 \"required\": [\"name\"]}"]
    (let [result (.validate validator schema)]
      (if (.isValid result)
        (println "Schema is valid!")
        (doseq [error (.getErrors result)]
          (println (.getMessage error)))))))

Instance Validation Example

(ns myapp.validation
  (:import [org.json_structure.validation InstanceValidator ValidationResult]))

(defn validate-instance []
  (let [validator (InstanceValidator.)
        schema "{\"type\": \"string\"}"
        instance "\"Hello, Clojure!\""]
    (let [result (.validate validator instance schema)]
      (println (str "Valid: " (.isValid result))))))

Idiomatic Notes:

Supported Types

Primitive Types

Temporal Types

Other Types

Compound Types

Validation Options

import org.json_structure.validation.ValidationOptions;

ValidationOptions options = new ValidationOptions()
    .setStopOnFirstError(false)           // Continue collecting all errors
    .setMaxValidationDepth(100)           // Maximum schema nesting depth
    .setAllowDollar(true)                 // Allow $ in property names (for metaschemas)
    .setAllowImport(true)                 // Enable $import/$importdefs processing
    .setExternalSchemas(Map.of(           // Sideloaded schemas for import resolution
        "https://example.com/address.json", addressSchema
    ));

SchemaValidator validator = new SchemaValidator(options);

Sideloading External Schemas

When using $import to reference external schemas, you can provide those schemas directly instead of fetching them from URIs:

import org.json_structure.validation.SchemaValidator;
import org.json_structure.validation.ValidationOptions;
import org.json_structure.validation.ValidationResult;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;

ObjectMapper mapper = new ObjectMapper();

// External schema that would normally be fetched
JsonNode addressSchema = mapper.readTree("""
    {
        "$schema": "https://json-structure.org/meta/core/v0/#",
        "$id": "https://example.com/address.json",
        "type": "object",
        "properties": {
            "street": { "type": "string" },
            "city": { "type": "string" }
        }
    }
    """);

// Main schema that imports the address schema
JsonNode mainSchema = mapper.readTree("""
    {
        "$schema": "https://json-structure.org/meta/core/v0/#",
        "type": "object",
        "properties": {
            "name": { "type": "string" },
            "address": { "$ref": "#/definitions/Imported/Address" }
        },
        "definitions": {
            "Imported": {
                "$import": "https://example.com/address.json"
            }
        }
    }
    """);

// Sideload the address schema - keyed by URI
ValidationOptions options = new ValidationOptions()
    .setAllowImport(true)
    .setExternalSchemas(Map.of(
        "https://example.com/address.json", addressSchema
    ));

SchemaValidator validator = new SchemaValidator(options);
ValidationResult result = validator.validate(mainSchema);
System.out.println("Valid: " + result.isValid());

Building

mvn clean package

Testing

mvn test

License

MIT License - see LICENSE file for details.