<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-openapi</artifactId>
<version>5.0.12</version>
</dependency>
Vert.x OpenAPI 契约引擎 (vertx-openapi)
Vert.x OpenAPI 扩展为 Vert.x 提供了针对 OpenAPI 3(支持 3.0 与 3.1 版本)规范的响应式契约驱动开发能力。
Vert.x OpenAPI 能够:
-
解析并严格校验 OpenAPI 契约定义。
-
依据 OpenAPI 契约解析并校验入站 HTTP 请求。
-
依据 OpenAPI 契约解析并校验出站 HTTP 响应。
引入依赖
要在项目中使用 Vert.x OpenAPI,请在构建描述文件中添加以下依赖:
-
Maven(在
pom.xml中):
-
Gradle(在
build.gradle文件中):
dependencies {
compile 'io.vertx:vertx-openapi:5.0.12'
}
OpenAPIContract 契约对象
使用 Vert.x OpenAPI 时,第一步总是从你的 API 契约文件中异步构建 OpenAPIContract 实例:
String pathToContract = "../../myContract.json"; // 支持 JSON 或 YAML 格式
Future<OpenAPIContract> contract = OpenAPIContract.from(vertx, pathToContract);
出于安全防护考量,本库不会主动从公网下载契约引用的外部 URL 资源。若契约包含外部引用,必须预先拉取至本地并通过参数一并注册至 OpenAPIContract。
|
以下示例展示了契约包含外部引用时的加载方式:
paths:
/pets:
get:
operationId: listPets
parameters:
- name: query
schema:
$ref: 'https://example.com/pet-components#/components/schemas/Query'
String pathToContract = "../../myContract.json";
String pathToComponents = "../../myComponents.json";
Map<String, String> additionalContractFiles = new HashMap<>();
additionalContractFiles.put("https://example.com/pet-components", pathToComponents);
Future<OpenAPIContract> contract =
OpenAPIContract.from(vertx, pathToContract, additionalContractFiles);
在实例化 OpenAPIContract 期间,框架会对契约本身执行格式校验;若契约违反 OpenAPI 规范或使用了尚未支持的高级特性,将抛出异常拦截。
|
遍历 Path、Operation 与 Parameter
OpenAPIContract 提供了便捷的方法遍历契约中的路径(Path)、操作(Operation)及参数(Parameter)元数据:
OpenAPIContract contract = getContract();
for (Path path : contract.getPaths()) {
for (Parameter pathParameter : path.getParameters()) {
// 读取参数对象的元数据
pathParameter.isRequired();
pathParameter.getSchema();
}
for (Operation operation : path.getOperations()) {
// 读取操作对象的元数据
operation.getOperationId();
operation.getRequestBody();
operation.getParameters();
}
}
厂商扩展指令 (Extensions)
Vert.x OpenAPI 支持自定义扩展属性 x-vertx-openapi-urldecode,用以指定 cookie 或 header 参数在解析时是否需要执行 URL 解码(默认值为 false;而 query 与 path 参数始终会自动解码):
paths:
/forceEncoding:
get:
operationId: forceEncoding
parameters:
- in: header
name: headerWithEncodedContent
x-vertx-openapi-urldecode: true
schema:
type: string
入站请求合法性校验
RequestValidator 提供了丰富的 validate 方法来严密校验到来的 HTTP 请求:
OpenAPIContract contract = getContract();
RequestValidator validator = RequestValidator.create(vertx, contract);
vertx.createHttpServer().requestHandler(httpServerRequest -> {
// 显式传入 operationId 可以避免系统重复计算当前路由,性能更优:
validator.validate(httpServerRequest, "yourOperationId")
.onSuccess(validatedRequest -> {
// 获取校验合法的请求体与标头
Buffer body = validatedRequest.getBody();
MultiMap headers = validatedRequest.getHeaders();
});
}).listen(0);
出站响应合法性校验
ResponseValidator 用于在服务返回前校验出站响应数据是否符合 OpenAPI 契约规范。校验通过后返回的 ValidatedResponse 可直接安全发送给客户端:
OpenAPIContract contract = getContract();
ResponseValidator validator = ResponseValidator.create(vertx, contract);
JsonObject cat = new JsonObject().put("name", "foo");
ValidatableResponse response =
ValidatableResponse.create(200, cat.toBuffer(), APPLICATION_JSON.toString());
vertx.createHttpServer().requestHandler(httpServerRequest -> {
validator.validate(response, "yourOperationId")
.onSuccess(validatedResponse -> {
// 响应数据符合契约,直接下发给客户端:
validatedResponse.send(httpServerRequest.response());
});
});
异常处理与错误诊断
若请求或响应未通过校验,系统将抛出 ValidatorException。
当由于数据内容不符合声明的 JSON Schema 时,将抛出其子类 SchemaValidationException,你可以通过该异常提取关联的 OutputUnit 进行细粒度根因分析。