Springdocs:为分页响应指定显式类型

tct7dpnv  于 2022-12-18  发布在  Spring
关注(0)|答案(1)|浏览(107)

我正在为我的应用程序进行“全局搜索”。目前,我正在使用hibernate-search来搜索多个不同对象的示例,并将它们返回给用户。相关代码如下所示:

Search.session(entityManager)
      .search(ModelA.classs, ModelB.class)
      .where(...)
      .sort(...)
      .fetch(skip, count);

Skip和count是根据Pageable计算的,结果用于创建Page的示例,该示例将返回给控制器。
这和我预期的一样,但是swagger-docs生成的类型显然不知道Page中的类型是什么,因此使用Object。我想公开正确的类型,因为我使用它们来为前端应用程序生成类型。
我可以将类型设置为数组,当重写模式时,如下所示:

@ArraySchema(schema = @Schema(anyOf = {ModelA.class, ModelB.class}))
public Page<?> search(Pageable pageable) {

然而,这只是忽略了页面,也是不正确的。
我尝试的下一件事是扩展PageImpl,覆盖getContent方法,并在此方法上指定相同的模式,但这根本没有包含在输出中。
接下来是我自己实现Page<T>(后来删除了对Page<T>的implements引用),并在getContentiterator和字段本身上指定相同的模式,但也没有效果。
我如何告诉spring-docs,结果页面的内容可能是什么?

bmp9r5qi

bmp9r5qi1#

我在试图解决类似问题时偶然发现了这个问题。从这个线程Springdoc with a generic return type中得到启发,我想出了下面的解决方案,它似乎也适用于您的情况。
我引入了一个存根类,它只充当响应的Schema:

private class PageModel(
  @Schema(oneOf = [ModelA::class, ModelB::class]))
  content: List<Object>
): PageImpl<Object>(content)

然后,我这样注解我的控制器:

@Operation(
  responses = [
    ApiResponse(
      responseCode = "200",
      content = [Content(schema = Schema(implementation = PageModel::class))]
    )
  ]
)
fun getPage(pageable: Pageable): Page<Object>

这生成了以下API响应:

"PageModel": {
    "properties": {
      "content": {
        "items": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/ModelA"
            },
            {
              "$ref": "#/components/schemas/ModelB"
            }
          ],
          "type": "object"
        },
        "type": "array"
      },
    ... -> more page stuff from spring's PageImpl<>


在API调用的“响应”部分:

"responses": {
      "200": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PageModel"
            }
          }
        },
        "description": "OK"
      }

所有生成的openapi doc在返回Page时都类似于自动生成的json,它只是将“content”数组属性重写为具有特定类型。

相关问题