带有additionalProperties的Swagger架构失败

时间:2016-10-26 01:26:34

标签: json validation jsonschema swagger-2.0

我想在REST API调用的主体中发布JSON对象。此data对象的属性DATA包含强制timestamp属性,然后是一系列各种属性,具体取决于Data对象的来源。据我所知,additionalProperties适用于此,默认为false或指定每个未定义属性的架构对象。

遵循Swagger YAML

/my/path:
  post:
    tags: [Tag]
    description: Description
    parameters:
    - name: data
      in: body
      description: The actual data.
      required: false
      type: object
      schema:
        $ref: "#/definitions/Data"

definitions/
  Data:
    type: object
    properties:
      source:
        type: string
      data:
        type: object
        properties:
          timestamp:
            type: string
            format: date-time
        additionalProperties:
          type: string

应该传递两个对象发送:

{
  "source": "A",
  "data": {
    "timestamp": "2016-10-26T01:12:40.329Z",
  }
}

{
  "source": "B",
  "data": {
    "timestamp": "2016-10-26T01:12:40.329Z",
    "newProp":"newValue"
  }
}

但是我收到的只是验证错误: ValidationError: child "data" fails because ["test" is not allowed]

有什么我做错了或者我误解了文档中描述的属性: http://swagger.io/specification/

2 个答案:

答案 0 :(得分:1)

我不确定your solution是否让您解决了问题。我发现与原始问题架构存在一些差异:

  • timestamp现在使用date代替datetime格式。
  • 现在需要
  • timestamp
  • additionalProperties设置为true

然而,Swagger中有一些关于additionalProperties的模糊限制,我们documented in detail here

基本上,虽然根据Swagger规范,您的原始模式完全有效,但swagger-core Java库将无法正确处理它。它会丢弃您明确定义的timestamp属性,或者会丢弃additionalProperties

令人惊讶的是,修复程序是将data属性的嵌入式架构提取到其自己的顶级架构定义:

definitions:

  Data:
    type: object
    properties:
      source:
        type: string
      data:
        $ref: "#/definitions/DataValues"

  DataValues:
    type: object
    properties:
      timestamp:
        type: string
        format: date-time
    additionalProperties:
      type: string  

我认为您修改后的架构无法正常运行,因为swagger-core会忽略additionalProperties布局值truefalse。显然这是规范中的疏忽; Swagger didn't intend支持JSON Schema的这个方面。

答案 1 :(得分:-1)

我实际上是自己想出来的,供参考:

definitions/
  Data:
    type: object
    properties:
      source:
        type: string
      data:
        required:
         - timestamp
        type: object
        properties:
          timestamp:
            type: string
            format: date
        additionalProperties: true