【问题标题】:openapi-generator doesn't generate response headers for Java client using Spring Webclientopenapi-generator 不使用 Spring Webclient 为 Java 客户端生成响应标头
【发布时间】:2021-07-29 06:41:39
【问题描述】:

我们有一个声明响应头的 openapi 文件(已验证),例如

    "responses": {
      "200": {
        "description": "OK",
        "schema": {
          "type": "object",
          "properties": {
            "results": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/CourseV2"
              }
            },
            "paging": {
              "$ref": "#/definitions/PagingInfo"
            }
          },
          "required": [
            "results"
          ]
        },
        "headers": {
              "X-RateLimit-Limit": {
                "type": "integer",
                "description": "Request limit per hour."
              },
              "X-RateLimit-Remaining": {
                "type": "integer",
                "description": "The number of requests left for the time window."
              },
              "X-RateLimit-Reset": {
                "type": "string",
                "format": "date-time",
                "description": "The UTC date/time at which the current rate limit window resets."
              }              
          }           
      },

使用openapi-generator项目(maven或cli)生成的java webclient客户端,调用的返回类型不包括响应头,ApiClient类中的invokeAPI方法也不提供对响应头的访问。 实际上,ApiClient 调用方法正在返回返回类型的 Mono/Flux,因此不允许获取响应标头

public <T> Mono<T> invokeAPI(String path, HttpMethod method, Map<String, Object> pathParams, MultiValueMap<String, String> queryParams, Object body, HttpHeaders headerParams, MultiValueMap<String, String> cookieParams, MultiValueMap<String, Object> formParams, List<MediaType> accept, MediaType contentType, String[] authNames, ParameterizedTypeReference<T> returnType) throws RestClientException {
    final WebClient.RequestBodySpec requestBuilder = prepareRequest(path, method, pathParams, queryParams, body, headerParams, cookieParams, formParams, accept, contentType, authNames);
    return requestBuilder.retrieve().bodyToMono(returnType);
}

据我所知,使用 Spring Webclient 访问响应标头的唯一方法是使用 toEntity,它提供 ResponseEntity 方法(以及 .getHeaders)而不是 bodyToMono。

我错过了什么吗?

【问题讨论】:

  • 您找到解决方案了吗?我看到了类似的问题。
  • @Upen 看看我下面的评论

标签: java spring-webflux spring-webclient openapi-generator


【解决方案1】:

openapi-generator 的基于 spring 的模板确实没有提及响应标头。但是,生成器核心引擎支持这些标头,并且某些生成器的模板包含/some/对它们的支持。具体可以看scala-akka-client的模板:https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/scala-akka-client/api.mustache#L38

另外,用于 Java-Spring 模板的 Swagger 注解允许为给定的响应指定 ResponseHeaders。

到目前为止一切顺利。可以尝试为选定的生成器增强模板。如果是 Java/Spring 生成器,它将是 https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/JavaSpring/api.mustache

不过,目前的 openapi-generator 数据模型似乎有些不正确。

首先,responseHeaders 绑定到一个方法,而不是该方法的特定响应。这意味着对于不同的响应不能有不同的标头(例如,一个用于200,另一个用于412),这似乎是一个严重的缺陷。

其次,为了使生成器产生头文件所必需的类型(特别是枚举),这些头文件应该使用内置模式,所有模式都将放入#/components/schemas/ 和然后从相应的头文件中引用:

components:
  headers:
    Repeatability-Result:
      description: |
        a header to implement server-side machinery for idempotency of requests
        complying to OASIS Repeatable Requests Version 1.0
        https://docs.oasis-open.org/odata/repeatable-requests/v1.0/repeatable-requests-v1.0.html
      schema:
        $ref: '#/components/schemas/RepeatabilityResult'
      required: true
  ...
  schemas:
    RepeatabilityResult:
      description: |
        a header to implement server-side machinery for idempotency of requests
        complying to OASIS Repeatable Requests Version 1.0
        https://docs.oasis-open.org/odata/repeatable-requests/v1.0/repeatable-requests-v1.0.html
      type: string
      enum:
        - accepted
        - rejected

接下来,生成的类型不包含在 {{{imports}}} 中,因此需要手动处理。

此外,头类型描述似乎在生成器类型定义中不可挽回地丢失了。

最后,现在我不明白如何正确 Java/WebFlux 特定的 API 方法定义应如下所示。

我可以像这样将responseHeaders 包含在@ApiResponse 定义中:

@ApiResponse(value = 204,
    responseHeaders = {
        @ResponseHeader(name = "ETag", response = String.class),
        @ResponseHeader(name = "Repeatability-Result", response = org.example.RepeatabilityResult.class)
    },
    message = ....
)
<webflux-specific API method declaration>

但它似乎仅供参考,并没有带来任何新功能。仍然必须手动将必要的标头放入响应中,而无需框架的任何支持/验证。

我可以向 OpenAPI-Generator 提交错误,但首先我想了解一个合适的解决方案是什么样的。

【讨论】:

    猜你喜欢
    • 2021-08-08
    • 2022-10-05
    • 2022-07-23
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    相关资源
    最近更新 更多