dev.harrel:json-schema Help

Evaluator factories

EvaluatorFactory is responsible for the creation of evaluators. It is used during a schema parsing process.

public interface EvaluatorFactory { Optional<Evaluator> create(SchemaParsingContext ctx, String fieldName, JsonNode fieldNode); }

The create method is called for every JSON property-value pair present in a schema. Sometimes it may be surprising because not all JSON objects might seem like schemas. Consider this example:

{ "properties": { "maxLength": false } }

The create method will be called twice:

  1. for pair properties - object

  2. and for pair maxLength - boolean.

As maxLength keyword only makes sense with numeric values, this may seem a bit odd, but such scenarios are commonly found in meta-schemas. Please remember to handle such cases properly in your custom keywords as well.

Evaluator factory builder

Most of the time implementing factory from scratch is not necessary. It is recommended to use builder instead. It allows binding a specific keyword to an evaluator provider.

To create such a binding, call:

EvaluatorFactory factory = new EvaluatorFactory.Builder() /* In rare cases when the value of the keyword is not important */ .withKeyword("customKeyword", () -> new CustomEvaluator()) /* When value of the keyword is needed */ .withKeyword("anotherKeyword", (node) -> new AnotherEvaluator(node)) /* When context is needed as well, mostly for applicators */ .withKeyword("thirdKeyword", (ctx, node) -> new ThirdEvaluator(ctx, node)) .build();

Schema parsing

Validator might contain multiple evaluator factories, and they complement each other. If one factory does not support given keyword, the next one in order is used.

Ordering and combining multiple factories into one factory are done by:

EvaluatorFactory rootFactory = EvaluatorFactory.compose(factory1, factory2, factory3);

Let's consider an example with a keyword x which is supported only by factory3:

  1. factory1 returns empty optional.

  2. factory2 returns empty optional.

  3. factory3 returns an actual evaluator.

What if keyword y is supported by both factory2 and factory3?

  1. factory1 returns empty optional.

  2. factory2 returns an actual evaluator.

  3. factory3 is never called as evaluator was already provided.

04 August 2025