You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为含自嵌套结构的对象编写FieldDescriptor及OpenAPI文档

解决递归嵌套对象的FieldDescriptor与OpenAPI定义问题

首先,我们来拆解你遇到的两个核心问题:递归结构的FieldDescriptor标注,以及payload未文档化的报错。


1. 先修正核心结构不匹配问题

你提供的报错payload里,myObject是一个数组,但你的OpenAPI定义里myObject是对象(type: object)——这是导致"未文档化"报错的直接原因!

如果你的API确实返回myObject作为数组,那需要调整OpenAPI定义:

components:
  schemas:
    myObject:
      type: object
      properties:
        values:
          type: array
          description: an array of 'STRING', 'BOOLEAN', 'NUMBER', or 'myObject'
          items:
            oneOf:
              - type: string
              - type: integer
              - type: boolean
              - $ref: '#/components/schemas/myObject'
    # 新增数组类型的定义
    myObjectArray:
      type: array
      items:
        $ref: '#/components/schemas/myObject'

如果这只是笔误,实际myObject应该是对象,那修正payload为:

{
  "myObject": {
    "values":[
      { "values":[ "pasta" ] },
      { "values":[ "pizza" ] },
      { "values":[ "mandolino" ] }
    ]
  }
}

2. 编写支持无限嵌套的递归FieldDescriptor

Java里直接创建递归的静态List<FieldDescriptor>会有初始化问题,我们可以用延迟加载的方式实现递归引用:

public static List<FieldDescriptor> getMyObjectDescriptor() {
    // 定义嵌套对象的字段描述,递归引用自身的描述符
    FieldDescriptor nestedMyObject = fieldWithPath("values[]")
            .description("Can be a string, number, boolean, or nested myObject")
            .type(JsonFieldType.VARIES)
            .subFields(getMyObjectDescriptor());

    return List.of(
        fieldWithPath("values")
            .type(JsonFieldType.ARRAY)
            .description("Array containing strings, numbers, booleans, or nested myObject instances")
            .optional()
            .subFields(List.of(nestedMyObject))
    );
}

如果你使用的是SpringDoc这类支持Schema引用的库,也可以直接关联OpenAPI的递归Schema,更简洁:

public static List<FieldDescriptor> myObjectDescriptor = List.of(
    fieldWithPath("values")
        .type(JsonFieldType.ARRAY)
        .description("May be an array of 'STRING', 'BOOLEAN', 'NUMBER', or 'myObject'")
        .optional()
        .itemsSchemaRef("#/components/schemas/myObject")
);

3. 简化版:不标注数组内部细节的解决方案

如果不想详细标注嵌套层级,至少要覆盖到嵌套对象的values字段,避免未文档化报错:

public static List<FieldDescriptor> myObjectDescriptor = List.of(
    fieldWithPath("values")
        .type(JsonFieldType.ARRAY)
        .description("May be an array of 'STRING', 'BOOLEAN', 'NUMBER', or 'myObject'")
        .optional(),
    // 覆盖嵌套对象的values字段,支持任意层级
    fieldWithPath("values[].values")
        .type(JsonFieldType.ARRAY)
        .description("Nested values array in a myObject instance")
        .optional()
);

关键补充:OpenAPI递归结构的正确写法

虽然你之前注释了oneOf,但要准确描述递归结构,oneOf是必须的(除非有特殊限制):

components:
  schemas:
    myObject:
      type: object
      properties:
        values:
          type: array
          description: An array of strings, numbers, booleans, or nested myObject instances
          items:
            oneOf:
              - type: string
              - type: integer
              - type: boolean
              - $ref: '#/components/schemas/myObject'

内容的提问来源于stack exchange,提问作者beegotsy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:22:54