Skip to content

Commit

Permalink
Improve schema retrieval docs (#959)
Browse files Browse the repository at this point in the history
  • Loading branch information
justin-tay authored Feb 7, 2024
1 parent e60f81f commit 5dc929e
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 26 deletions.
110 changes: 85 additions & 25 deletions doc/schema-retrieval.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,100 @@ 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<String, String> 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<String, String> 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<String, RegistryEntry> 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.

### 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<String, String> 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
Expand All @@ -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) {
Expand Down Expand Up @@ -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)));
```
2 changes: 1 addition & 1 deletion doc/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down

0 comments on commit 5dc929e

Please sign in to comment.