web-dev-qa-db-ja.com

条件付きで必要なjsonSchema属性

JsonSchemaでは、「必須」属性を使用して、定義済みフィールドが必須かどうかを指定できます。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "properties": {
        "header": {
            "type": "object",
            "properties": {
                "messageName": {
                    "type": "string"
                },
                "messageVersion": {
                    "type": "string"
                }
            },
            "required": [
                "messageName",
                "messageVersion"
            ]
        }
    },
    "required": [
        "header"
    ]
}

特定のケースでは、messageVersionフィールドが必須ではないようにします。このフィールドの必須性を条件付きにする方法はありますか?

74
tom redfern

状況に応じて、いくつかの異なるアプローチがあります。条件付きでフィールドを要求する4つの異なる方法を考えることができます。

依存関係

dependenciesキーワードは、requiredキーワードの条件付きバリエーションです。 dependenciesのForeachプロパティ。検証されるJSONにプロパティが存在する場合、そのキーに関連付けられたスキーマも有効である必要があります。 「foo」プロパティが存在する場合、「bar」プロパティが必要です

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "dependencies": {
    "foo": { "required": ["bar"] }
  }
}

スキーマにrequiredキーワードのみが含まれる場合は、短い形式もあります。

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "dependencies": {
    "foo": ["bar"]
  }
}

含意

条件がフィールドの値に依存する場合、含意と呼ばれるブール論理概念を使用できます。 「AはBを意味します」とは、Aが真の場合、Bも真でなければならないことを意味します。含意は「!AまたはB」として表現することもできます。 「foo」プロパティが「bar」に等しくないか、「bar」プロパティが必要です。または、言い換えると:「foo」プロパティが「bar」に等しい場合、「bar」プロパティが必要です

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "anyOf": [
    {
      "not": {
        "properties": {
          "foo": { "const": "bar" }
        },
        "required": ["foo"]
      }
    },
    { "required": ["bar"] }
  ]
}

「foo」が「bar」と等しくない場合、#/anyOf/0は一致し、検証は成功します。 「foo」が「bar」に等しい場合、#/anyOf/0は失敗し、anyOf検証が成功するには#/anyOf/1が有効でなければなりません。

列挙型

条件が列挙型に基づいている場合、もう少し簡単です。 「foo」には「bar」または「baz」を指定できます。 「foo」が「bar」に等しい場合、「bar」が必要です。 「foo」が「baz」に等しい場合、「baz」が必要です。

{
  "type": "object",
  "properties": {
    "foo": { "enum": ["bar", "baz"] },
    "bar": { "type": "string" },
    "baz": { "type": "string" }
  },
  "anyOf": [
    {
      "properties": {
        "foo": { "const": "bar" }
      },
      "required": ["bar"]
    },
    {
      "properties": {
        "foo": { "const": "baz" }
      },
      "required": ["baz"]
    }
  ]
}

If-Then-Else

JSON Schema(draft-07) への比較的新しい追加により、ifthen、およびelseキーワードが追加されます。 「foo」プロパティが「bar」に等しい場合、「bar」プロパティが必要です

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "if": {
    "properties": {
      "foo": { "const": "bar" }
    },
    "required": ["foo"]
  },
  "then": { "required": ["bar"] }
}

EDIT 12/23/2017:含意セクションが更新され、If-Then-Elseセクションが追加されました。

EDIT 06/04/2018:If-Then-Elseのバグ修正およびシングルトンenumsを更新してconstを使用します。

192