Vert.x OpenAPI
Vert.x OpenAPI 继承了 Vert.x Web 用以支持 OpenAPI 3 ,同时为您提供了简便的接口来构建一个符合您接口协议的Vert.x Web 路由器。
Vert.x OpenAPI 可以做到如下事情:
-
解析并校验您的 OpenAPI 3 协议
-
根据您的约束来生成路由器(带有正确的路径以及方法)
-
提供基于您接口协议的请求解析和校验的功能,该功能用 Vert.x Web Validation 实现。
-
挂载必要的安全处理器
-
在 OpenAPI 风格和 Vert.x 风格之间转换路径
-
用 Vert.x Web API Service 来将请求路由到事件总线
使用 Vert.x OpenAPI
要使用Vert.x OpenAPI,您需要添加如下依赖:
-
Maven (在您的
pom.xml
文件):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-openapi</artifactId>
<version>4.0.3</version>
</dependency>
-
Gradle (在您的
build.gradle
文件):
dependencies {
compile 'io.vertx:vertx-web-openapi:4.0.3'
}
RouterBuilder
RouterBuilder
是这个模块的主要元素,它提供了用来挂载请求处理器的接口,并且生成最终的 Router
要使用 Vert.x Web OpenAPI ,您必须用 RouterBuilder.create
方法并传入您的接口协议来实例化 RouterBuilder
例如从本地文件系统来加载一个约束:
RouterBuilder.create(vertx, "src/main/resources/petstore.yaml").onComplete(ar -> {
if (ar.succeeded()) {
// 约束加载成功
RouterBuilder routerBuilder = ar.result();
} else {
// router builder 初始化失败
Throwable exception = ar.cause();
}
});
您可以从一个远程约束构建一个 router builder :
RouterBuilder.create(
vertx,
"https://raw.githubusercontent" +
".com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml"
).onComplete(ar -> {
if (ar.succeeded()) {
// 约束加载成功
RouterBuilder routerBuilder = ar.result();
} else {
// router builder 初始化失败
Throwable exception = ar.cause();
}
});
您可以通过配置 OpenAPILoaderOptions
以获取私有的远程约束:
OpenAPILoaderOptions loaderOptions = new OpenAPILoaderOptions()
.putAuthHeader("Authorization", "Bearer xx.yy.zz");
RouterBuilder.create(
vertx,
"https://raw.githubusercontent" +
".com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml",
loaderOptions
).onComplete(ar -> {
if (ar.succeeded()) {
// 约束加载成功
RouterBuilder routerBuilder = ar.result();
} else {
// router builder 初始化失败
Throwable exception = ar.cause();
}
});
您可以用 RouterBuilderOptions
来修改 router builder 的各种行为:
routerBuilder.setOptions(new RouterBuilderOptions());
获取operation
使用 handler
为一个operation来挂载处理器,
使用 failureHandler
来挂载失败处理器。
您可以 在一个 operation 当中添加多个处理器 ,而不覆盖已经存在的处理器。
例如:
routerBuilder
.operation("awesomeOperation")
.handler(routingContext -> {
RequestParameters params =
routingContext.get(ValidationHandler.REQUEST_CONTEXT_KEY);
RequestParameter body = params.body();
JsonObject jsonBody = body.getJsonObject();
// 处理请求体
}).failureHandler(routingContext -> {
// 处理失败
});
重要
|
没有 |
Vert.x OpenAPI 为您挂载了正确的 ValidationHandler
,所以您才可以获取到请求参数和请求体。
请参考 Vert.x Web 校验文档 来学习如何获取请求参数以及请求体,并学习如何管理校验失败的处理方式。
将 AuthenticationHandler
映射到 OpenAPI 安全约束
您可以将一个 AuthenticationHandler
映射到一个接口协议当中定义的安全约束。
例如,给出一个名为 security_scheme_name
接口约束:
routerBuilder.securityHandler("security_scheme_name", authenticationHandler);
您可以挂载包含在Vert.x Web中模块中的 AuthenticationHandler
,例如:
routerBuilder.securityHandler("jwt_auth",
JWTAuthHandler.create(jwtAuthProvider));
当您生成 Router
之后,router builder会解析operation所必须的安全约束。
如果一个operation所必须的 AuthenticationHandler
缺失,则这个过程会失败。
调试/测试时,您可以用 setRequireSecurityHandlers
来禁用这个检验。
未实现的错误
如果未指定处理器,那么Router builder会为一个operation自动挂载一个默认的处理器。
这个默认的处理器会让 routing context 处于 405 Method Not Allowed
或者 501 Not Implemented
错误状态。
您可以用 setMountNotImplementedHandler
启用/禁用它,并且您可以用 errorHandler
自定义这个错误的处理方式。
响应内容类型处理器
当接口协议需要的时候,Router builder 自动挂载一个 ResponseContentTypeHandler
处理器。
您可以用 setMountResponseContentTypeHandler
禁用这个特性。
operation 模型
如果您在处理请求的时候需要获取到operation模型,那么您可以配置router builder,从而用 setOperationModelKey
将其放入 RoutingContext
。
options.setOperationModelKey("operationModel");
routerBuilder.setOptions(options);
// 添加一个用这个operation模型的处理器
routerBuilder
.operation("listPets")
.handler(
routingContext -> {
JsonObject operation = routingContext.get("operationModel");
routingContext
.response()
.setStatusCode(200)
.setStatusMessage("OK")
// 以"listPets"为 operation id 回写响应
.end(operation.getString("operationId"));
});
请求体处理器
Router builder自动挂载一个 BodyHandler
用以管理请求体。
您可以用 bodyHandler
来配置 BodyHandler
对象(例如,更换上传目录)
multipart/form-data
校验
校验处理器像如下描述来区分文件上传和表单属性:
-
如果参数中没有编码相关的字段:
-
如果参数存在
type: string
和format: base64
,或者存在format: binary
,那么它就是 content-type请求头为application/octet-stream
的一个请求。 -
否则是一个表单请求
-
-
如果参数存在编码相关字段,则是一个文件上传的请求。
对于表单属性,他们被解析、转换为Json、然后校验, 然而对于文件上传请求,校验处理器仅仅检查存在性和Content-Type。
自定义全局处理器
如果您需要挂载一个处理器,而这个处理器在您路由器中每个operation执行之前都需要执行特定操作,那么您可以用 rootHandler
生成路由器
万事俱备,生成路由器并使用:
Router router = routerBuilder.createRouter();
HttpServer server =
vertx.createHttpServer(new HttpServerOptions().setPort(8080).setHost(
"localhost"));
server.requestHandler(router).listen();
这个方法可能会失败并抛出 RouterBuilderException
。
提示
|
如果您需要挂载所有router builder生成的具有相同父级路径的路由器,您可以用
|