在 OpenAPI 中启用异步服务器 API 按需为 Jersey 生成代码
Enabling the Asynchronous Server API in OpenAPI generated code for Jersey on demand
我们通过 gradle(即 openapi-generator-gradle-plugin)使用 OpenAPI 来生成 Jersey 资源。一般来说,这很好用。
生成的方法如下所示:
public Response getSomeFoo(@ApiParam(...) String someParam, ...) { ...
但我们也希望支持使用 Asynchronous Server API 的方法。
理论上我们可以将所有生成的同步方法更改为异步方法,即调整模板文件 api.mustache
和 apiService.mustache
,其中我们将 Response
替换为 void
并添加 @Suspended final AsyncResponse asyncResponse
作为第一个参数(加上添加导入等)。
但是我们把所有请求从同步处理转为异步处理是没有意义的。
所以我的问题是:我们怎样才能实现某种 "switch" 来在输入文件中指明我们想要为每个方法生成什么样的实现 (synchronously/asynchronously)?
我正在考虑编写一个新的生成器来读取例如输入规范文件中的一个标签,并将其放入一个布尔变量中,该变量在模板文件中进行评估。这可行吗?有没有类似的问题已经解决了?或者你对我有什么其他的想法吗?
谢谢!
现在我自己找到了一个解决方案,幸运的是它非常方便:OpenAPI 为我们提供了 Extensions – 我使用其中之一来解决问题。我在规范 JSON 中使用自定义 x-async-enabled
扩展,如下所示:
"paths": {
"/fubaz": {
"get": {
"summary": "My Fubaz resource",
"operationId": "fubaz",
"x-async-enabled": true,
...
然后我在模板中使用此信息以便有条件地为各个方法生成不同的签名(文件 api.mustache
):
{{#operation}}
public {{#vendorExtensions.x-async-enabled}}void{{/vendorExtensions.x-async-enabled}}{{^vendorExtensions.x-async-enabled}}Response{{/vendorExtensions.x-async-enabled}} {{nickname}}({{#vendorExtensions.x-async-enabled}}@Suspended final AsyncResponse asyncResponse, {{/vendorExtensions.x-async-enabled}}{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}},{{/allParams}})
throws Exception {
{{#vendorExtensions.x-async-enabled}}
delegate.{{nickname}}(asyncResponse, {{#allParams}}{{#isFormParam}}{{#isFile}}{{paramName}}InputStream, {{paramName}}Detail{{/isFile}}{{/isFormParam}}{{^isFile}}{{paramName}}{{/isFile}}{{^isFormParam}}{{#isFile}}{{paramName}}{{/isFile}}{{/isFormParam}}, {{/allParams}});
{{/vendorExtensions.x-async-enabled}}
{{^vendorExtensions.x-async-enabled}}
return delegate.{{nickname}}({{#allParams}}{{#isFormParam}}{{#isFile}}{{paramName}}InputStream, {{paramName}}Detail{{/isFile}}{{/isFormParam}}{{^isFile}}{{paramName}}{{/isFile}}{{^isFormParam}}{{#isFile}}{{paramName}}{{/isFile}}{{/isFormParam}}, {{/allParams}});
{{/vendorExtensions.x-async-enabled}}
}
{{/operation}}
当然我也必须调整导入并在 apiService.mustache
中做基本相同的事情。这对我有用,我现在可以简单地标记我想用异步服务器处理的内容 API.
我们通过 gradle(即 openapi-generator-gradle-plugin)使用 OpenAPI 来生成 Jersey 资源。一般来说,这很好用。
生成的方法如下所示:
public Response getSomeFoo(@ApiParam(...) String someParam, ...) { ...
但我们也希望支持使用 Asynchronous Server API 的方法。
理论上我们可以将所有生成的同步方法更改为异步方法,即调整模板文件 api.mustache
和 apiService.mustache
,其中我们将 Response
替换为 void
并添加 @Suspended final AsyncResponse asyncResponse
作为第一个参数(加上添加导入等)。
但是我们把所有请求从同步处理转为异步处理是没有意义的。
所以我的问题是:我们怎样才能实现某种 "switch" 来在输入文件中指明我们想要为每个方法生成什么样的实现 (synchronously/asynchronously)?
我正在考虑编写一个新的生成器来读取例如输入规范文件中的一个标签,并将其放入一个布尔变量中,该变量在模板文件中进行评估。这可行吗?有没有类似的问题已经解决了?或者你对我有什么其他的想法吗?
谢谢!
现在我自己找到了一个解决方案,幸运的是它非常方便:OpenAPI 为我们提供了 Extensions – 我使用其中之一来解决问题。我在规范 JSON 中使用自定义 x-async-enabled
扩展,如下所示:
"paths": {
"/fubaz": {
"get": {
"summary": "My Fubaz resource",
"operationId": "fubaz",
"x-async-enabled": true,
...
然后我在模板中使用此信息以便有条件地为各个方法生成不同的签名(文件 api.mustache
):
{{#operation}}
public {{#vendorExtensions.x-async-enabled}}void{{/vendorExtensions.x-async-enabled}}{{^vendorExtensions.x-async-enabled}}Response{{/vendorExtensions.x-async-enabled}} {{nickname}}({{#vendorExtensions.x-async-enabled}}@Suspended final AsyncResponse asyncResponse, {{/vendorExtensions.x-async-enabled}}{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}},{{/allParams}})
throws Exception {
{{#vendorExtensions.x-async-enabled}}
delegate.{{nickname}}(asyncResponse, {{#allParams}}{{#isFormParam}}{{#isFile}}{{paramName}}InputStream, {{paramName}}Detail{{/isFile}}{{/isFormParam}}{{^isFile}}{{paramName}}{{/isFile}}{{^isFormParam}}{{#isFile}}{{paramName}}{{/isFile}}{{/isFormParam}}, {{/allParams}});
{{/vendorExtensions.x-async-enabled}}
{{^vendorExtensions.x-async-enabled}}
return delegate.{{nickname}}({{#allParams}}{{#isFormParam}}{{#isFile}}{{paramName}}InputStream, {{paramName}}Detail{{/isFile}}{{/isFormParam}}{{^isFile}}{{paramName}}{{/isFile}}{{^isFormParam}}{{#isFile}}{{paramName}}{{/isFile}}{{/isFormParam}}, {{/allParams}});
{{/vendorExtensions.x-async-enabled}}
}
{{/operation}}
当然我也必须调整导入并在 apiService.mustache
中做基本相同的事情。这对我有用,我现在可以简单地标记我想用异步服务器处理的内容 API.