2015-07-21 69 views
0

我在嘗試創建一個既使用oneOf又使用通用引用子模式的模式時遇到問題,以避免必須複製部分架構。 該模式應確認對外觀如下JSON:如何使用oneOf以及共同的子模式(V4)

{ 
    "createdDate": "2015-01-20T17:10:05Z", 
    "createdBy": "testUser", 
    "lastModifiedDate": "2015-01-20T17:10:05Z", 
    "lastModifiedBy": "testUser", 
    "fileUrl": { 
    "path": "/path/to/file", 
    "fileName": "file.pdf" 
    }, 
    "referenceType": "person", 
    "fileType": "certificate", 
    "personId": "12345" 
} 

由此看來,常見的部分是:

{ 
    "createdDate": "2015-01-20T17:10:05Z", 
    "createdBy": "testUser", 
    "lastModifiedDate": "2015-01-20T17:10:05Z", 
    "lastModifiedBy": "testUser", 
    "fileUrl": { 
    "path": "/path/to/file", 
    "fileName": "file.pdf" 
    } 
} 

剩下的3場總是在名稱相同,所有必需的,但允許的枚舉值會有所不同。

所以對於其餘3的模式可能是下列之一:

{ 
"properties": { 
    "referenceType": { 
     "type": "string", 
     "enum": [ 
      "vehicle" 
     ] 
    }, 
    "fileType": { 
     "type": "string", 
     "enum": [ 
      "registration document" 
     ] 
    }, 
    "vehicleId": { 
     "type": "string", 
     "pattern": "[^ ]" 
    } 
}, 
"required": [ 
    "vehicleId" 
] 
} 

OR

{ 
    "properties": { 
     "referenceType": { 
      "type": "string", 
      "enum": [ 
       "person" 
      ] 
     }, 
     "fileType": { 
      "type": "string", 
      "enum": [ 
       "certificate" 
      ] 
     }, 
     "personId": { 
      "type": "string", 
      "pattern": "[^ ]" 
     } 
    }, 
    "required": [ 
     "personId" 
    ] 
} 

我似乎無法創建一個模式,由此我可以避免重複公共字段,並擁有oneOf,並在整個模式中將additionalProperties設置爲false。 對於下面的例子,試圖將additionalProperties設置爲false會導致驗證錯誤。是否有可能做我想做的事情?

{ 
    "type": "object", 
    "$schema": "http://json-schema.org/draft-04/schema#", 
    "definitions": { 
     "commonFile": { 
      "properties": { 
       "createdDate": { 
        "type": "string", 
        "format": "date-time" 
       }, 
       "createdBy": { 
        "type": "string", 
        "pattern": "[^ ]" 
       }, 
       "lastModifiedDate": { 
        "type": "string", 
        "format": "date-time" 
       }, 
       "lastModifiedBy": { 
        "type": "string", 
        "pattern": "[^ ]" 
       }, 
       "fileUrl": { 
        "type": "object", 
        "additionalProperties": false, 
        "properties": { 
         "path": { 
          "type": "string", 
          "pattern": "[^ ]" 
         }, 
         "fileName": { 
          "type": "string", 
          "pattern": "[^ ]" 
         } 
        }, 
        "required": [ 
         "path", 
         "fileName" 
        ] 
       } 
      } 
     } 
    }, 
    "oneOf": [{ 
      "allOf": [ 
       {"$ref": "#/definitions/commonFile"}, 
       { 
        "properties": { 
         "referenceType": { 
          "type": "string", 
          "enum": [ 
           "person" 
          ] 
         }, 
         "fileType": { 
          "type": "string", 
          "enum": [ 
           "certificate" 
          ] 
         }, 
         "personId": { 
          "type": "string", 
          "pattern": "[^ ]" 
         } 
        }, 
        "required": [ 
         "personId" 
        ] 
       } 
      ] 
     }, { 
      "allOf": [ 
       {"$ref": "#/definitions/commonFile"}, 
       { 
        "properties": { 
         "referenceType": { 
          "type": "string", 
          "enum": [ 
           "vehicle" 
          ] 
         }, 
         "fileType": { 
          "type": "string", 
          "enum": [ 
           "registration document" 
          ] 
         }, 
         "vehicleId": { 
          "type": "string", 
          "pattern": "[^ ]" 
         } 
        }, 
        "required": [ 
         "vehicleId" 
        ] 
       } 
      ] 
     } 
    ], 
    "required": [ 
     "createdDate", 
     "createdBy", 
     "lastModifiedDate", 
     "lastModifiedBy", 
     "fileUrl", 
     "referenceType", 
     "fileType" 
    ] 
} 

回答

0

我建議設置additionalPropertiesfalse。通常最好是安靜地忽略未定義的屬性。下面的模式是你必須做的,以實現你的目標。

{ 
    "$schema": "http://json-schema.org/draft-04/schema#", 
    "type": "object", 
    "properties": { 
    "createdDate": { "type": "string", "format": "date-time" }, 
    "createdBy": { "type": "string", "pattern": "[^ ]" }, 
    "lastModifiedDate": { "type": "string", "format": "date-time" }, 
    "lastModifiedBy": { "type": "string", "pattern": "[^ ]" }, 
    "fileUrl": { 
     "type": "object", 
     "additionalProperties": false, 
     "properties": { 
     "path": { "type": "string", "pattern": "[^ ]" }, 
     "fileName": { "type": "string", "pattern": "[^ ]" } 
     }, 
     "required": ["path", "fileName"] 
    }, 
    "referenceType": { "type": "string" }, 
    "fileType": { "type": "string" }, 
    "personId": {}, 
    "vehicleId": {} 
    }, 
    "additionalProperties": false, 
    "anyOf": [ 
    { 
     "properties": { 
     "referenceType": { "enum": ["person"] }, 
     "fileType": { "enum": ["certificate"] }, 
     "personId": { "type": "string", "pattern": "[^ ]" } 
     }, 
     "required": ["personId"], 
     "not" : { "required": ["vehicleId"] } 
    }, 
    { 
     "properties": { 
     "referenceType": { "enum": ["vehicle"] }, 
     "fileType": { "enum": ["registration document"] }, 
     "vehicleId": { "type": "string", "pattern": "[^ ]" } 
     }, 
     "required": ["vehicleId"], 
     "not" : { "required": ["personId"] } 
    } 
    ], 
    "required": ["createdDate", "createdBy", "lastModifiedDate", "lastModifiedBy", "fileUrl", "referenceType", "fileType"] 
} 

我做的第一件事是刪除所有無關的allOf s。只需要一個anyOf。我在主模式中定義了常用屬性。這些變化在anyOf條款中有所描述。

如果設置additionalPropertiesfalse,額外的架構(如allOfoneOf,並且anyOf)無法引入新的特性。這意味着此模式中將允許的所有屬性必須包含在聲明additionalPropertiesfalse的模式中。這就是爲什麼我在主模式中聲明瞭referenceType,fileType,personIdvechicleId。現在

的問題是,additionalProperties不再排除vehicleIdreferenceTypepersonpersonIdreferenceTypevehicle。爲了確保不被允許,我添加了not條款。

如果添加第三個變體,限制其他屬性變得更加困難。這不僅僅是將referenceType添加到anyof架構數組中。您還必須將新屬性添加到主架構,並禁止現有referenceTypes所有的新類型。您必須對整個架構進行更改,而不僅僅是正在更改的區域。這就是爲什麼設置additionalPropertiesfalse通常不是最好的主意。

+0

謝謝@Jason,這似乎工作。'additionalProperties'當然不能按我預期的方式工作 – user1149405

相關問題