<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-codegen</artifactId>
<version>5.0.12</version>
<classifier>processor</classifier>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-api-service</artifactId>
<version>5.0.12</version>
</dependency>
Vert.x Web API Service
Vert.x Web API Service 帮助你通过 Vert.x EventBus(事件总线)以 RPC 风格透明解耦并处理 HTTP 请求。
EventBus 提供了极其强大的服务间解耦能力,包括集群内跨进程/跨机器的动态负载均衡与流量分发。更多细节欢迎查阅 Event Bus 官方文档。
该模块基于 Vert.x Service Proxy 的设计思想,允许你创建 Web API Service 服务消费者,并通过内置 Handler 自动将前端 HTTP 请求打包代理至后端对应的服务接口。
使用 Vert.x API Service
在工程构建文件中添加依赖:
-
Maven(在
pom.xml中):
-
Gradle(在
build.gradle文件中):
dependencies {
annotationProcessor 'io.vertx:vertx-codegen:5.0.12:processor'
annotationProcessor 'io.vertx:vertx-web-api-service:5.0.12'
compile 'io.vertx:vertx-web-api-service:5.0.12'
}
引入 vertx-codegen 是为了在编译期通过注解处理器(APT)自动生成代理接口的胶水代码。若仅使用 RouteToEBServiceHandler,则无需引入生成器。
若需要在不同多语言环境间调用该服务接口,需引入对应的语言扩展包(如 Groovy 需引入 vertx-lang-groovy)。
将 HTTP 请求透明代理至 Web API Service
通过 RouteToEBServiceHandler,你可以将 HTTP 请求直接桥接至 EventBus。
该 Handler 会自动从 RoutingContext 中提取上下文数据封装为 ServiceRequest,并通过 EventBus 请求后端,最终将返回的 ServiceResponse 自动回写给客户端:
router
.get("/hello")
.handler(validationHandler)
.handler(
RouteToEBServiceHandler
.build(eventBus, "greeters.myapplication", "hello")
);
你还可以配置专用的 DeliveryOptions(如自定义 RPC 超时时间):
router
.get("/hello")
.handler(validationHandler)
.handler(
RouteToEBServiceHandler
.build(eventBus, "greeters.myapplication", "hello",
new DeliveryOptions().setSendTimeout(1000))
);
在挂载 RouteToEBServiceHandler 之前,必须 先行挂载负责提取并校验请求参数的 ValidationHandler,否则无法自动向下游服务传递请求参数。
|
定义 Web API Service 接口规范
在深入之前,推荐先阅读 Service Proxy 官方文档。
假设我们在 Router 中声明了以下两条路由:
router.get("/api/transactions")
.handler(
ValidationHandlerBuilder.create(repository)
.queryParameter(optionalParam("from", stringSchema()))
.queryParameter(optionalParam("to", stringSchema()))
.build()
).handler(
RouteToEBServiceHandler.build(eventBus, "transactions.myapplication",
"getTransactionsList")
);
router.post("/api/transactions")
.handler(
ValidationHandlerBuilder.create(repository)
.body(json(objectSchema()))
.build()
).handler(
RouteToEBServiceHandler.build(eventBus, "transactions.myapplication",
"putTransaction")
);
GET /api/transactions 接收两个可选查询参数 from 与 to;POST /api/transactions 接收 JSON 请求体。
接下来我们定义处理这两个接口的 Java 业务接口 TransactionService。
接口中的方法名称需与构建 RouteToEBServiceHandler 时指定的 action 严格对应。参数签名需遵循以下规范:
-
最后一个参数类型必须为
Handler<AsyncResult<ServiceResponse>>(异步结果回调) -
倒数第二个参数类型必须为
ServiceRequest(请求上下文元数据) -
从第一个到倒数第三个参数,系统会自动从
RequestParameters中按名称自动提取并做类型转换,但参数类型需遵循 Service Proxy 的规范约束
方法参数名即为提取参数时的 Key;特殊的参数名 body 专门用于提取 HTTP 请求体:
@WebApiServiceGen
interface TransactionService {
void getTransactionsList(String from, String to, ServiceRequest context, Handler<AsyncResult<ServiceResponse>> resultHandler);
void putTransaction(JsonObject body, ServiceRequest context, Handler<AsyncResult<ServiceResponse>> resultHandler);
}
当客户端访问 TransactionService#getTransactionsList 时,生成的代理层会自动从 ServiceRequest 中提取 from 与 to;在 putTransaction 中则自动提取 JSON 请求体。
若定义了符合规范的 Vert.x DataObject(如 Transaction),系统还支持直接映射为强类型对象:
void putTransaction(Transaction body, ServiceRequest context, Handler<AsyncResult<ServiceResponse>> resultHandler);
实现 Web API Service 业务逻辑
实现接口时,通过回调传入 ServiceResponse 即可构建响应。系统提供了诸如 completedWithJson 或 completedWithPlainText 等快捷工厂方法:
resultHandler.handle(
Future.succeededFuture(
ServiceResponse.completedWithJson(new JsonArray())
)
);
发生业务异常时:
resultHandler.handle(
Future.failedFuture(
new HttpException(555, "处理发生未知异常")
)
);
ServiceRequest 数据对象
ServiceRequest 是 RoutingContext 的轻量级可序列化版本,跨 EventBus 传递:
-
getHeaders():获取原始请求头 -
getParams():包含所有解析合规的参数集合 -
getUser():包含登录用户的 principal,未登录时为 null -
getExtra():支持配置自定义透传附加字段
ServiceResponse 数据对象
封装了响应头、HTTP 状态码及响应负载内容。
暴露并注册你的 Web API Service
将实现类注册到 EventBus 指定地址上:
TransactionService transactionService = new TransactionServiceImpl();
// 在 EventBus 上绑定服务
ServiceBinder transactionServiceBinder = new ServiceBinder(vertx);
transactionServiceBinder
.setAddress("transactions.myapplication")
.register(TransactionService.class, transactionService);
与 OpenAPI 深度集成
Vert.x Web API Service 提供了 OpenAPIRouterHandler,可直接绑定至 OpenAPIRoute,自动将符合 OpenAPI 规范的外部请求流转至后端 RPC 服务代理:
OpenAPIContract contract = getContract();
ResponseValidator responseValidator = ResponseValidator.create(vertx, contract);
OpenAPIRoute route = routerBuilder.getRoute("getPets");
OpenAPIRouterHandler handler = OpenAPIRouterHandler.create(vertx,
route.getOperation(), responseValidator);
route.addHandler(handler);
在 OpenAPI 规范文件中,只需在对应接口中配置 x-vertx-event-bus 扩展字段,指明目标 EventBus 地址即可完成无缝联动:
paths:
/pets:
get:
operationId: listPets
x-vertx-event-bus:
address: myEventbusAddress
method: getPetById