Vert.x OpenAPI 路由

预览

Vert.x OpenAPI 路由基于 Vert.x OpenAPI,并且只提供路由功能。

Vert.x OpenAPI 路由可以

  • 根据您的 OpenAPI 契约生成路由,包含正确的路径和方法。

使用 Vert.x OpenAPI 路由

要使用 Vert.x OpenAPI 路由,请将以下依赖项添加到构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

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

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

RouterBuilder

使用 RouterBuilder,您可以基于传入的 OpenAPIContract 轻松生成 Vert.x Web 路由。

OpenAPIContract contract = getContract();
RouterBuilder routerBuilder = RouterBuilder.create(vertx, contract);
Router router = routerBuilder.createRouter();

// In case that a BodyHandler was applied before, it is necessary to pass a RequestExtractor
RouterBuilder.create(vertx, contract, RequestExtractor.withBodyHandler());

RouterBuilder 提供了访问生成路由的方法。这些路由可以通过添加自定义处理器或启用/禁用验证进行自定义。

OpenAPIRoute getPetsRoute = routerBuilder.getRoute("getPets");

// Disables validation for this route.
getPetsRoute.setDoValidation(false);

for (OpenAPIRoute route : routerBuilder.getRoutes()) {
  // Access the operation object from the contract
  Operation operation = route.getOperation();

  // Add a custom handler
  route.addHandler(routingContext -> {
    // do something
  });

  // Add a failure handler
  route.addFailureHandler(routingContext -> {
    // do something
  });
}

成功验证传入请求后,验证后的参数和请求正文将存储在 RoutingContext 中,并可在您的自定义处理器中访问。

OpenAPIRoute putPetRoute = routerBuilder.getRoute("putPet");

putPetRoute.addHandler(routingContext -> {
  ValidatedRequest validatedRequest =
    routingContext.get(RouterBuilder.KEY_META_DATA_VALIDATED_REQUEST);

  validatedRequest.getBody(); // returns the body
  validatedRequest.getHeaders(); // returns the header
  // ..
  // ..
});

定义安全处理器

安全性是 OpenAPI 规范的一个重要方面。security 允许您定义安全处理器。

用户需要为 OpenAPI 契约中定义的每个安全方案调用此方法。否则,在生成路由时将导致失败。此外,提供契约中未定义的其他处理器也将导致失败。

对于 apiKeyhttp 安全方案,可以自动配置安全处理器。对于其他情况,您需要提供一个自定义处理器工厂,该工厂将从 OpenAPI 契约中指定的配置作为输入。

例如

RouterBuilder routerBuilder = RouterBuilder.create(vertx, contract);

// Add a security handler for "api_key" security scheme
// configuration will be automatically read from the contract and applied
// to the handler
routerBuilder
  .security("api_key")
  .apiKeyHandler(APIKeyHandler.create(provider));

// Add a security handler for "http" "bearer" security scheme
routerBuilder
  .security("http_bearer")
  .httpHandler(JWTAuthHandler.create(providerJWT));

当然,也支持 OAuth2/OpenID Connect,考虑到这些模式配置起来更为复杂,因此您需要提供一个能够按需创建处理器的工厂,而不是提供一个简单的配置对象。该工厂将接收来自契约的配置,或者在 openIdConnect 的情况下接收配置发现 URL。

RouterBuilder routerBuilder = RouterBuilder.create(vertx, contract);

// Add a security handler for "oauth2" security scheme
routerBuilder
  .security("oauth2")
  .oauth2Handler("/callback", flowsConfig -> {
    // flowsConfig is a JsonObject with the configuration for the flows
    // you can use it to create the "providerOAuth2" instance
    return OAuth2AuthHandler.create(
      vertx,
      providerOAuth2,
      // there should a relation between this origin and the callback above
      "https://my-application-server.com/callback");
  });

发现机制听起来可能更简单,如果您正在使用兼容 OpenID 的服务器,则可以使用 openIdConnect 安全方案。

RouterBuilder routerBuilder = RouterBuilder.create(vertx, contract);

// Add a security handler for "openIdConnect" security scheme
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,
          // there should a relation between this origin and the callback above
          "https://my-application-server.com/callback");
      });
  });