如何使用 springdoc-openapi 使所有可选 OpenAPI 参数可为空?

M. *_*tin 6 java spring spring-boot openapi springdoc

springdoc -openapi库会根据生成的 OpenAPI 文档中的要求自动标记某些属性。例如,注释为 的属性@NotNull将包含在生成的 YAML 文件的必需属性列表中。

该库不做的一件事是将可选属性标记为nullable: true. 但是,默认情况下,Spring Boot 应用程序将接受null请求并返回null可选属性的响应。这意味着 OpenAPI 文档和端点的行为之间存在差异。

手动将任何单个属性标记为可为空非常简单:只需添加@Schema(nullable = true)到字段或访问器即可。但是,在具有多个属性的大型模型中,我宁愿以与required属性相同的方式自动确定它。也就是说,如果不需要该属性,我希望它是nullable,反之亦然。

如何将我的可选属性标记为nullable: truespringdoc-openapi 生成的 OpenAPI 文档?

例子

import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotNull;

public class RequiredExample {
    @NotNull
    private String key;

    private String value;

    public String getKey() { return key; }
    public void setKey(String key) { this.key = key; }
    public String getValue() { return value; }
    public void setValue(String value) { this.value = value; }
}
Run Code Online (Sandbox Code Playgroud)

生成的 OpenAPI 文档:

"components": {
  "schemas": {
    "RequiredExample": {
      "required": [
        "key"
      ],
      "type": "object",
      "properties": {
        "key": {
          "type": "string"
        },
        "value": {
          "type": "string"
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

所需的 OpenAPI 文档:

"components": {
  "schemas": {
    "RequiredExample": {
      "required": [
        "key"
      ],
      "type": "object",
      "properties": {
        "key": {
          "type": "string"
        },
        "value": {
          "type": "string"
          "nullable": true
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

M. *_*tin 1

一种解决方案是创建一个 springdoc-openapi OpenApiCustomiserSpring bean,它将所有属性设置为nullable,除非它们位于属性列表中required。这种方法受益于内置的 springdoc-openapi 支持@NotNull和其他此类注释,因为required属性将根据此类属性的存在以标准方式计算。

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.Schema;
import org.springdoc.core.customizers.OpenApiCustomiser;
import org.springframework.stereotype.Component;
import java.util.Map;

@Component
public class NullableIfNotRequiredOpenApiCustomizer implements OpenApiCustomiser {
    @Override
    @SuppressWarnings({"rawtypes", "unchecked"})
    public void customise(OpenAPI openApi) {
        for (Schema schema : openApi.getComponents().getSchemas().values()) {
            if (schema.getProperties() == null) {
                continue;
            }

            ((Map<String, Schema>) schema.getProperties()).forEach((String name, Schema value) -> {
                if (schema.getRequired() == null || !schema.getRequired().contains(name)) {
                    value.setNullable(true);
                }
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)