ENSEMBLU SchemaGuard
Project Axiom

SchemaGuard

You give it data and a schema. It tells you, in one word, whether the data is safe to use.

Every piece of data coming into your system — an API request, a config file, an upload — either matches the shape you expect, or it doesn't.

SchemaGuard checks that, and hands you back exactly one of two things:

✓ Valid
The data is safe to use, exactly as-is.
✗ Invalid
A plain-English reason why, and exactly where.

No crashes. No stack traces. No half-processed data leaking through.

What it replaces

The usual way
  • Annotate a class, hope the framework wires it correctly
  • Reflection scans your objects at runtime
  • Bad data throws an exception, sometimes deep in unrelated code
  • Debugging means chasing a stack trace back to the real cause
With SchemaGuard
  • Write the schema once, as a plain file
  • No annotations, no reflection, no hidden scanning
  • Bad data never throws — you get a clear answer back
  • The error tells you exactly what's wrong and where

How you actually use it

Three lines. That's the entire interaction — everything else is internal.

Checking a payload against a schema
final var result = SchemaGuard
                    .checkContent(incomingData)
                    .basedOnSchemaInPath("user-profile")
                    .withAxiomParser();
1

Hand it the raw data you received.

2

Tell it which schema file to check against, by name.

3

Get back a clear yes/no — never a crash.

In practice: validating real JSON

Most incoming data isn't in Axiom's own format — it's plain JSON from an API request, a webhook, a queue message. SchemaGuard doesn't care. Plug in any parser you like, and it validates the result the exact same way.

Validating an incoming JSON payload against a named schema file
final var data = SchemaGuard
                    .checkContent(substance)
                    .basedOnSchemaInPath("schemas/account_query_schema")
                    .withParser(toJson())
                    .getOrThrow();

private static Function<String, PersistentMap<String, Object>> toJson() {
    return s -> JsonParser.take(s).openBuffer().ensureRootIsObject().parseObject();
}

Same call shape either way — .withAxiomParser() for Axiom's own format, .withParser(...) for anything else. The validation logic underneath doesn't change; only how the raw text gets turned into data does.

Writing a schema: the .axiom file

A schema is a plain file, not code. Write it once, drop it in schemas/, reference it by name — nothing to compile or annotate.

schemas/account_query_schema.axiom
{
  strict: true
  required: [account_id, email]

  properties: {
    account_id: {
      type: string
      pattern: "^[A-Z0-9]{8,12}$"
    }
    email: {
      type: string
      pattern: "^[^@]+@[^@]+\\.[^@]+$"
    }
    age: {
      type: integer
      min: 13
      max: 120
    }
    tags: {
      minItems: 1
      maxItems: 10
      record: { type: string }
    }
    role: {
      type: string
      enum: [admin, member, guest]
    }
  }
}
Key What you write
typestring, integer, double, boolean — object and array can be left out, they're inferred automatically from properties / record
requireda list of field names that must be present
stricttrue to reject any field not listed below
propertiesthe schema for each field of an object
recordthe schema every item in an array must match
min / maxsmallest and largest allowed number
minLength / maxLengthshortest and longest allowed string
patterna regular expression the string must match
minItems / maxItemssmallest and largest allowed list size
enumthe exact list of values allowed

Why this matters at scale

At high transaction volume, the cost of bad data isn't a crash you notice — it's a corrupted record you don't, until it's downstream and expensive to trace back. SchemaGuard rejects malformed data at the door, with zero framework overhead, so the rest of the system only ever sees data it can trust.