【问题标题】:How to specify a property can be null or a reference with swagger如何指定一个属性可以是空的,也可以是带有招摇的引用
【发布时间】:2017-04-16 16:04:17
【问题描述】:

How to specify a property as null or a reference? 讨论如何使用 jsonschema 将属性指定为 null 或引用。

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

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

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

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

答案的关键在于oneOf的使用。

我的问题的关键点:

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

  2. 在我的规范中的各个地方 property 可以是对此类对象的引用,也可以为 null。

如何使用不支持 oneOf 的 Swagger 或 anyOf?

注意:一些 swagger 实现使用 x-nullable(或类似的)来指定属性值可以为 null,但是,$ref 用它引用的对象替换对象,所以它会似乎对x-nullable 的任何使用都被忽略了。

【问题讨论】:

    标签: swagger openapi swagger-2.0


    【解决方案1】:

    OpenAPI 3.1

    将属性定义为$reftype: 'null' 中的anyOf

    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 将起作用。

    OpenAPI 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 规范存储库中进一步讨论:Reference objects don't combine well with “nullable”

    【讨论】:

    • 我在 .net 核心上使用 swashbuckle 5x,我想将 "nullable": true 添加到 "payload": { "$ref": "#/components/schemas/MyClass" },所以它是 "payload": { "nullable": true, "$ref": "#/components/schemas/MyClass" },有人知道这样做的 swashbuckle 选项吗?跨度>
    • @AdamDiament 请ask a new question
    • 谢谢海伦,我已经做到了here
    【解决方案2】:

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

    等待

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

    使用供应商扩展

    您可以像 x-oneOfx-anyOf 一样使用vendors extensions。我已经采取了这种艰难的方式:您必须升级所有使用'swagger工具'以考虑这些供应商扩展。

    就我而言,我们只需要:

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

    一年前,也许现在……

    重构您的 API

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

    【讨论】:

    • "Wait" - 是的,显然 v3 将支持 oneOf、anyOf,但是我们必须等待使用它的工具和库。
    • "Extensions" - 我在 python (w/ bravado-core) 中使用我的招摇,它没有你提到的扩展......无赖。
    • "重构" - 这需要简化我的 api 以适应规范...我需要规范以适应我的 api!对于返回 $ref-or-null now 的情况,我唯一能想到的另一件事是 not 返回在客户端的情况下的属性(我的case) 会将“未定义”视为“空”。但我讨厌这个主意。
    猜你喜欢
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2021-11-10
    • 2010-12-28
    • 2014-05-15
    相关资源
    最近更新 更多