Vert.x Json Schema

Vert.x Json Schema 为 Json Schema 规范提供了可扩展的异步实现。你可以使用 Json Schemas 来验证每个 JSON 结构。此模块提供

使用 Vert.x Json Schema

要使用 Vert.x Json Schema,请将以下依赖添加到你的构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-json-schema</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

dependencies {
  compile 'io.vertx:vertx-json-schema:5.0.1'
}

概念

JsonSchema

Schema 可以有两种形式存在

  • JSON,以 JSON 符号表示

  • 布尔值,如 true/false

JsonSchema 接口允许处理这两种类型,而无需持续检查底层类型。

SchemaRepository

SchemaRepository 存储 JsonSchema 实例。它执行 Schema 的解引用以加快验证速度。该存储库是一个简单的键值存储,这意味着它不允许重复的 ID。

该存储库可以创建知晓存储库中所有子 Schema 的 Validator 实例。

Validator

顾名思义,Validator 使用一个起始 Schema 验证一个对象。输出格式取决于配置。

解析 Schema

当处理多个 Schema 或子 Schema 时,建议使用 Repository

要解析 Schema,你首先需要一个 JsonSchema 和一些初始配置。由于 Schema 可以包含引用,因此验证器和存储库需要知晓你的应用程序的 baseUri。这允许你在其他子 Schema 中引用自己的 Schema。为了解引用目的,你不需要配置草案。

SchemaRepository repository =
  SchemaRepository.create(new JsonSchemaOptions().setBaseUri("https://vertx.com.cn"));

你可以将 JsonSchema 实例用于不同的 Validator,并且可以直接使用 JsonParser 解析不同的 JsonSchema

现在你可以解析 Schema 了

JsonSchema schema = JsonSchema.of(object);

// Or

repository.dereference(JsonSchema.of(object));

请记住,出于安全原因,此模块不会尝试下载任何引用的子 Schema。所有必需的子 Schema 都应提供给存储库对象。

验证

鉴于 JSON Schema 的动态性质以及条件 if-then-else,无法在流式场景中进行验证。因此,验证是一个阻塞操作。如果你意识到验证将是一个非常耗时的过程,建议在专门的线程池上运行验证或使用 executeBlocking。Schema 可以有两种状态

要验证 Schema

OutputUnit result = Validator.create(
    schema,
    new JsonSchemaOptions().setDraft(Draft.DRAFT7))
  .validate(json);

if (result.getValid()) {
  // Successful validation
} else {
  System.out.println("Validation failed due to " + result.getError() + " this is an error type: " + result.getErrorType());
}

如果验证失败,你可以检索 OutputErrorType 以帮助确定失败的原因。当前有 3 种 OutputErrorType

  • NONE(无),在未发现错误时使用。

  • INVALID_VALUE(无效值),在提供了一个值,但该值与给定 Schema 不匹配时使用。

  • MISSING_VALUE(缺失值),在值不存在,或存在的值不足但 Schema 要求时使用。

定义自定义 JSON 格式

默认情况下,Schema 验证器将对未知格式执行空操作(NOOP),因此它们将被视为有效输入。根据你决定使用的 JSON 规范,可能需要额外的格式检查。如果你需要定义额外的格式检查,你可以在创建 SchemaRepositoryValidator 时提供自己的 JsonFormatValidator 实现。

JsonFormatValidator customFormatValidator = (instanceType, format, instance) -> {
  if ("string".equals(instanceType) && "allUpercase".equals(format)) {
    if (instance.toString().equals(instance.toString().toUpperCase())) {
      return null;
    }
    return String.format("String does not match the format \"%s\"", format);
  }
  return null;
};

SchemaRepository repository = SchemaRepository.create(new JsonSchemaOptions(), customFormatValidator);

JsonSchema schema = JsonSchema.of(Schemas.stringSchema().toJson());
Validator validator = Validator.create(schema, new JsonSchemaOptions(), customFormatValidator);

从代码构建你的 Schema

如果你想从代码构建 Schema,你可以使用随附的 DSL。此功能仅支持 Draft-7。

首先,添加对 SchemasKeywords 的静态导入

创建 Schema

Schemas 中有用于创建 Schema 的静态方法

SchemaBuilder intSchemaBuilder = intSchema();
SchemaBuilder objectSchemaBuilder = objectSchema();

使用关键字

对于每个 Schema,你可以根据 Schema 的类型,添加使用 Keywords 方法构建的关键字

stringSchema()
  .with(format(StringFormat.DATETIME));
arraySchema()
  .with(maxItems(10));
schema() // Generic schema that accepts both arrays and integers
  .with(type(SchemaType.ARRAY, SchemaType.INTEGER));

定义 Schema 结构

根据你创建的 Schema,你可以定义一个结构。

创建一个包含某些属性 Schema 和额外属性 Schema 的对象 Schema

objectSchema()
  .requiredProperty("name", stringSchema())
  .requiredProperty("age", intSchema())
  .additionalProperties(stringSchema());

创建一个数组 Schema

arraySchema()
  .items(stringSchema());

创建一个元组 Schema

tupleSchema()
  .item(stringSchema()) // First item
  .item(intSchema()) // Second item
  .item(booleanSchema()); // Third item

$ref 和别名

要添加 $ref Schema,你可以使用 Schemas.ref 方法。要将 $id 关键字分配给 Schema,请使用 id

你还可以使用别名引用通过此 DSL 定义的 Schema。你可以使用 alias 为 Schema 分配别名。然后你可以使用 Schemas.refToAlias 引用带有别名的 Schema。

intSchema()
  .alias("myInt");

objectSchema()
  .requiredProperty("anInteger", refToAlias("myInt"));

使用 Schema

定义 Schema 后,你可以调用 toJson 以返回 Schema 的 JSON 表示。

JsonObject schema = objectSchema()
  .requiredProperty("name", stringSchema())
  .requiredProperty("age", intSchema())
  .additionalProperties(stringSchema())
  .toJson();