Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve schema retrieval docs #959

Merged
merged 1 commit into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading