如何用swagger指定一个属性可以为null或者引用

问题描述 投票:0回答:5

如何将属性指定为 null 或引用? 讨论如何使用 jsonschema 将属性指定为 null 或引用。

我希望用 swagger 做同样的事情。

回顾一下上面的答案,使用 jsonschema,可以这样做:

{
   "definitions": {
      "Foo": {
         # some complex object
      }
   },

   "type": "object",
   "properties": {
      "foo": {
         "oneOf": [
            {"$ref": "#/definitions/Foo"},
            {"type": "null"}
         ]
      }
   }
}

答案的关键点是使用

oneOf

我的问题要点:

  1. 我有一个复杂的物体,我想保持干燥,所以我把它放在一个 定义部分,以便在我的 swagger 规范中重用:其他属性的值;响应对象等

  2. 在我的规范中的各个地方 属性可以是对此类对象的引用或者为 null。

如何使用不支持

oneOf
或的 Swagger 指定这一点
anyOf

注意:一些 swagger 实现使用

x-nullable
(或类似的)来指定属性值可以为 null,但是,
$ref
用它引用的对象替换 对象,因此会出现
x-nullable
的任何使用被忽略。

swagger openapi swagger-2.0
5个回答
76
投票

开放API 3.1

将属性定义为

anyOf
$ref
type: 'null'

YAML 版本:

foo:
  anyOf:
    - type: 'null'   # Note the quotes around 'null'
    - $ref: '#/components/schemas/Foo'

JSON版本:

"foo": {
    "anyOf": [
        { "type": "null" },
        { "$ref": "#/components/schemas/Foo" }
    ]
}

为什么使用

anyOf
而不是
oneOf
?如果引用的模式本身允许空值,
oneOf
将失败验证,而
anyOf
可以工作。

开放API 3.0

YAML 版本:

foo:
  nullable: true
  allOf:
  - $ref: '#/components/schemas/Foo'

JSON版本:

"foo": {
    "nullable": true,
    "allOf": [
        { "$ref": "#/components/schemas/Foo" }
    ]
}

在 OAS 3.0 中,需要将

$ref
包装到
allOf
中,以便将
$ref
与其他关键字组合 - 因为
$ref
会覆盖任何同级关键字。 OpenAPI 规范存储库对此进行了进一步讨论:引用对象与“可空”不能很好地结合使用


8
投票

对于 OpenAPI 3.0,出于某种原因,使用

nullable: true
后跟
allOf
对于我正在使用的 OpenAPI 解释器不起作用。作为一种解决方法,我最终定义了一个名为 null_type
must-be-null
引用,我可以在
anyOf
构造中使用它。

像这样:

allOf:
  - anyOf:
      - $ref: "#/components/schemas/null_type"
      - $ref: "#/components/schemas/your_ref"
  - description: "optionally add other properties here..."

地点:

schemas:
  null_type:
    title: "OpenAPI 3.0 null-type ref"
    description: "for adding nullability to a ref"
    enum: [null]

  your_ref:
    ...

5
投票

做到这一点并不容易。甚至几乎不可能。您的选择:

等等

关于这个有一个很长的讨论,也许有一天会完成......

使用供应商扩展

您可以使用供应商扩展,例如x-oneOfx-anyOf。我已经采取了这种艰难的方式:您必须升级所有使用的“招摇工具”才能考虑到这些供应商扩展。

就我而言,我们需要“仅”:

  • 开发我们自己的具有自定义注释的 Jax-RS 解析器,以便从源中提取 swagger API 文件
  • 扩展 swagger-codegen 以考虑这些扩展,为我们的客户生成 java 代码
  • 开发我们自己的 swagger-ui:为了促进这项工作,我们添加了一个预处理步骤,将带有扩展的 swagger 模式转换为有效的 json 模式。在 javascript 中找到表示 json 模式的模块比 swagger 模式更容易。由于缺点,我们放弃了使用“尝试”按钮来测试 API 的想法。

那是一年前,也许现在......

重构您的 API

很多项目不需要anyOf和oneOf,为什么我们不需要?


1
投票

我在 .net6 webAPI 中使用 Swashbuckle 时遇到了类似的问题。我有一个属性,它是一个对象,但也可以为空。当对象为空时,无法反序列化它。

例如这有效并反序列化了

{
  "Foo":"bar"
  "Details" {
    "Test":"value",
    "Test2":"value"
  }
}

但这未能反序列化

{
  "Foo":"bar"
  "Details": null
}

为了解决此问题,我在我的 swagger 设置中添加了以下内容。

builder.Services.AddSwaggerGen(options =>
{
     options.UseAllOfToExtendReferenceSchemas();
});

生成了以下内容

"someObject": {
  "allOf": [
    {
      "$ref": "#/components/schemas/SomeObject"
    }
  ],
  "nullable": true
},

0
投票

我在 OpenAPI 3.0 中遇到了类似的问题,之前建议的解决方案对我不起作用:

foo:
  nullable: true
  allOf:
  - $ref: '#/components/schemas/Foo'

我发现了一种替代解决方案,使用

oneOf
来指定可为空对象,而无需创建单独的可为空引用:

foo:
  oneOf:
  - type: object
    nullable: true
  - $ref: '#/components/schemas/Foo'
© www.soinside.com 2019 - 2024. All rights reserved.