<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-openapi-router</artifactId>
<version>5.1.10</version>
</dependency>
Vert.x OpenAPI Router
Vert.x OpenAPI Router 基于 Vert.x OpenAPI 构建,专为 Vert.x Web 提供契约驱动的高性能路由自动化生成能力。
Vert.x OpenAPI Router 能够:
-
根据你定义的 OpenAPI 契约(OpenAPI Contract),自动生成包含正确路径、HTTP 方法与入参强校验的 Vert.x Web 路由器。
使用 Vert.x OpenAPI Router
若要在项目中使用 Vert.x OpenAPI Router,请在构建描述文件中添加以下依赖:
-
Maven(在
pom.xml中):
-
Gradle(在
build.gradle文件中):
dependencies {
compile 'io.vertx:vertx-web-openapi-router:5.1.10'
}
路由构建器 (RouterBuilder)
通过 RouterBuilder,你可以直接基于传入的 OpenAPIContract 契约实例,一键构建出完整的 Vert.x Web Router:
OpenAPIContract contract = getContract();
RouterBuilder routerBuilder = RouterBuilder.create(vertx, contract);
Router router = routerBuilder.createRouter();
// 若此前已全局挂载过 BodyHandler,需传入专属的 RequestExtractor 提取器
RouterBuilder.create(vertx, contract, RequestExtractor.withBodyHandler());
RouterBuilder 提供了丰富的检索方法来定位各个自动生成的路由。你可以为这些路由挂载自定义业务 Handler,或动态开启/关闭入参校验:
OpenAPIRoute getPetsRoute = routerBuilder.getRoute("getPets");
// 禁用针对该路由的自动入参校验
getPetsRoute.setDoValidation(false);
for (OpenAPIRoute route : routerBuilder.getRoutes()) {
// 从契约中获取对应的 Operation 操作定义元数据
Operation operation = route.getOperation();
// 追加自定义业务处理器
route.addHandler(routingContext -> {
// 处理核心业务逻辑
});
// 追加异常失败处理器
route.addFailureHandler(routingContext -> {
// 处理错误兜底逻辑
});
}
当传入的 HTTP 请求通过 OpenAPI 契约的强格式校验后,校验解析出的合法参数与请求体会被自动存入 RoutingContext,你可以在自定义业务 Handler 中直接读取:
OpenAPIRoute putPetRoute = routerBuilder.getRoute("putPet");
putPetRoute.addHandler(routingContext -> {
ValidatedRequest validatedRequest =
routingContext.get(RouterBuilder.KEY_META_DATA_VALIDATED_REQUEST);
validatedRequest.getBody(); // 获取校验合规的请求体
validatedRequest.getHeaders(); // 获取校验合规的请求头
// ..
});
定义安全鉴权处理器 (Define security handlers)
安全鉴权是 OpenAPI 规范的核心支柱。
通过 security 可以为契约中的安全方案(Security Schemes)配置对应的鉴权 Handler。
对于 OpenAPI 契约中声明的每一个安全方案,必须显式调用此方法注册对应的鉴权处理器;若有缺失,生成 Router 时将直接抛出异常;同样,若注册了契约之外多余的安全方案,也会导致校验失败报错。
对于 apiKey 与 HTTP bearer 类常规安全方案,系统支持开箱即用的自动装配;对于更复杂的方案,你只需提供一个工厂函数即可:
RouterBuilder routerBuilder = RouterBuilder.create(vertx, contract);
// 为 "api_key" 安全方案绑定处理器:
// 系统会自动从契约读取鉴权配置(如 Header/Query 位置及键名)并应用到 Handler
routerBuilder
.security("api_key")
.apiKeyHandler(APIKeyHandler.create(provider));
// 为 "http" "bearer" 安全方案绑定 JWT 鉴权处理器
routerBuilder
.security("http_bearer")
.httpHandler(JWTAuthHandler.create(providerJWT));
对于 OAuth2 与 OpenID Connect 这类复杂的授权流,工厂函数会接收契约配置或发现端点 URL,并据此构建定制化的 OAuth2 处理器:
RouterBuilder routerBuilder = RouterBuilder.create(vertx, contract);
// 为 "oauth2" 安全方案挂载处理器
routerBuilder
.security("oauth2")
.oauth2Handler("/callback", flowsConfig -> {
// flowsConfig 包含契约中声明的授权流配置 JsonObject
return OAuth2AuthHandler.create(
vertx,
providerOAuth2,
"https://my-application-server.com/callback");
});
// 为 "openIdConnect" 挂载自动发现与鉴权处理器
routerBuilder
.security("openIdConnect")
.openIdConnectHandler("/callback", discoveryUrl -> {
return OpenIDConnectAuth.discover(
vertx,
new OAuth2Options()
.setClientId("client-id")
.setClientSecret("client-secret"))
.map(openIdConnect -> {
return OAuth2AuthHandler.create(
vertx,
openIdConnect,
"https://my-application-server.com/callback");
});
});