标准规范 (Standards)
你当前正在浏览历史版本 Vert.x 4.4.9 的文档。 访问本页面的 最新版本。

Vert.x OpenAPI Router

Preview

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 中):

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-web-openapi-router</artifactId>
  <version>5.0.12</version>
</dependency>
  • Gradle(在 build.gradle 文件中):

dependencies {
  compile 'io.vertx:vertx-web-openapi-router:5.0.12'
}

路由构建器 (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");
      });
  });