From 5dc929e908689cf00194e278085bb4d2ff6354d1 Mon Sep 17 00:00:00 2001 From: Justin Tay <49700559+justin-tay@users.noreply.github.com> Date: Wed, 7 Feb 2024 21:24:44 +0800 Subject: [PATCH] Improve schema retrieval docs (#959) --- doc/schema-retrieval.md | 110 +++++++++++++++++++++++++++++++--------- doc/upgrading.md | 2 +- 2 files changed, 86 insertions(+), 26 deletions(-) diff --git a/doc/schema-retrieval.md b/doc/schema-retrieval.md index 697a974c8..43842e50a 100644 --- a/doc/schema-retrieval.md +++ b/doc/schema-retrieval.md @@ -6,6 +6,57 @@ In the event a schema references a schema identifier that is not a subschema res In the event that the schema does not define a schema identifier using the `$id` keyword, the retrieval IRI will be used as it's schema identifier. +## Loading Schemas from memory + +Schemas can be loaded through a map. + +```java +String schemaData = "{\r\n" + + " \"type\": \"integer\"\r\n" + + "}"; +Map schemas = Collections.singletonMap("https://www.example.com/integer.json", schemaData); +JsonSchemaFactory schemaFactory = JsonSchemaFactory + .getInstance(VersionFlag.V7, + builder -> builder.schemaLoaders(schemaLoaders -> schemaLoaders.schemas(schemas))); +``` + +Schemas can be loaded through a function. + +```java +String schemaData = "{\r\n" + + " \"type\": \"integer\"\r\n" + + "}"; +Map schemas = Collections.singletonMap("https://www.example.com/integer.json", schemaData); + JsonSchemaFactory schemaFactory = JsonSchemaFactory + .getInstance(VersionFlag.V7, + builder -> builder.schemaLoaders(schemaLoaders -> schemaLoaders.schemas(schemas::get))); +``` + +Schemas can also be loaded in the following manner. + +```java +class RegistryEntry { + private final String schemaData; + + public RegistryEntry(String schemaData) { + this.schemaData = schemaData; + } + + public String getSchemaData() { + return this.schemaData; + } +} + +String schemaData = "{\r\n" + + " \"type\": \"integer\"\r\n" + + "}"; +Map registry = Collections + .singletonMap("https://www.example.com/integer.json", new RegistryEntry(schemaData)); +JsonSchemaFactory schemaFactory = JsonSchemaFactory + .getInstance(VersionFlag.V7, builder -> builder + .schemaLoaders(schemaLoaders -> schemaLoaders.schemas(registry::get, RegistryEntry::getSchemaData))); +``` + ## Mapping Schema Identifier to Retrieval IRI The schema identifier can be mapped to the retrieval IRI by implementing the `SchemaMapper` interface. @@ -13,24 +64,42 @@ The schema identifier can be mapped to the retrieval IRI by implementing the `Sc ### Configuring Schema Mapper ```java -JsonSchemaFactory schemaFactory = JsonSchemaFactory.builder() - .schemaMappers(schemaMappers -> schemaMappers - .add(new CustomSchemaMapper()) - .addMetaSchema(JsonMetaSchema.getV7()) - .defaultMetaSchemaURI(JsonMetaSchema.getV7().getUri()) - .build(); +class CustomSchemaMapper implements SchemaMapper { + @Override + public AbsoluteIri map(AbsoluteIri absoluteIRI) { + String iri = absoluteIRI.toString(); + if ("https://www.example.com/integer.json".equals(iri)) { + return AbsoluteIri.of("classpath:schemas/integer.json"); + } + return null; + } +} + +JsonSchemaFactory schemaFactory = JsonSchemaFactory + .getInstance(VersionFlag.V7, + builder -> builder.schemaMappers(schemaMappers -> schemaMappers.add(new CustomSchemaMapper()))); ``` ### Configuring Prefix Mappings ```java -JsonSchemaFactory schemaFactory = JsonSchemaFactory.builder() - .schemaMappers(schemaMappers -> schemaMappers - .mapPrefix("https://", "http://") - .mapPrefix("http://json-schema.org", "classpath:")) - .addMetaSchema(JsonMetaSchema.getV7()) - .defaultMetaSchemaURI(JsonMetaSchema.getV7().getUri()) - .build(); +JsonSchemaFactory schemaFactory = JsonSchemaFactory + .getInstance(VersionFlag.V7, + builder -> builder + .schemaMappers(schemaMappers -> schemaMappers + .mapPrefix("https://json-schema.org", "classpath:") + .mapPrefix("http://json-schema.org", "classpath:"))); +``` + +### Configuring Mappings + +```java +Map mappings = Collections + .singletonMap("https://www.example.com/integer.json", "classpath:schemas/integer.json"); + +JsonSchemaFactory schemaFactory = JsonSchemaFactory + .getInstance(VersionFlag.V7, + builder -> builder.schemaMappers(schemaMappers -> schemaMappers.mappings(mappings))); ``` ## Customizing Network Schema Retrieval @@ -45,11 +114,8 @@ The `SchemaLoader` interface must implemented and the implementation configured ```java public class CustomUriSchemaLoader implements SchemaLoader { - private static final Logger LOGGER = LoggerFactory.getLogger(CustomUriSchemaLoader.class); - private final String authorizationToken; - private final HttpClient client; public CustomUriSchemaLoader(String authorizationToken) { @@ -86,13 +152,7 @@ Within the `JsonSchemaFactory` the custom `SchemaLoader` must be configured. ```java CustomUriSchemaLoader uriSchemaLoader = new CustomUriSchemaLoader(authorizationToken); -JsonSchemaFactory schemaFactory = JsonSchemaFactory.builder() - .schemaLoaders(schemaLoaders -> schemaLoaders.add(uriSchemaLoader)) - .addMetaSchema(JsonMetaSchema.getV7()) - .defaultMetaSchemaURI(JsonMetaSchema.getV7().getUri()) - .build(); -JsonSchema jsonSchema = schemaFactory.getSchema(schemaUri); -for (ValidationMessage validationMessage : jsonSchema.validate(jsonNodeRecord)) { - // handle the validation messages -} +JsonSchemaFactory schemaFactory = JsonSchemaFactory + .getInstance(VersionFlag.V7, + builder -> builder.schemaLoaders(schemaLoaders -> schemaLoaders.add(uriSchemaLoader))); ``` diff --git a/doc/upgrading.md b/doc/upgrading.md index 6da6ae54b..830432dc3 100644 --- a/doc/upgrading.md +++ b/doc/upgrading.md @@ -93,7 +93,7 @@ The following are removed and replaced by `SchemaLoader` and `SchemaMapper`. * `URLFetcher` - Replaced by `UriSchemaLoader`. * `URNURIFactory` - No replacement as `URIFactory` isn't required anymore. -The `SchemaLoader` and `SchemaMapper` are configured in the `JsonSchemaFactory.Builder`. +The `SchemaLoader` and `SchemaMapper` are configured in the `JsonSchemaFactory.Builder`. See [Customizing Schema Retrieval](schema-retrieval.md). As per the specification. The `format` keyword since Draft 2019-09 no longer generates assertions by default.