web-dev-qa-db-ja.com

JSONスキーマを使用して、特定の必須フィールドを持つ「任意の」タイプのスキーマを指定します

次のJSONスキーマがあるとしましょう

{
 "name":"Product",
 "type":"object",
 "properties":{
   "id":{
     "type":"number",
     "required":true
   },
   "name":{
     "description":"Name of the product",
     "required":true
   },
   "price":{
     "required":true,
     "type": "number",
     "minimum":0,
     "required":true
   },
   "tags":{
     "type":"array",
     "items":{
       "type":"any"
     }
   }
 }
}

ただし、タグを配列にするのではなく、ルートスキーマの一部にしたいと思います。したがって、任意のプロパティを指定できますが、「id」、「name」、「price」に特に注意します。正しい方法は次のうちどれですか。完全に間違っているのはどれですか。

{
 "name":"Product",
 "type":"object",
 "properties":{
   "id":{
     "type":"number",
     "required":true
   },
   "name":{
     "description":"Name of the product",
     "required":true
   },
   "price":{
     "required":true,
     "type": "number",
     "minimum":0,
     "required":true
   }
 },
 "additionalProperties": {
     "type":"any"
 }
}

{
 "name":"Product",
 "type":"object",
 "properties":{
   "id":{
     "type":"number",
     "required":true
   },
   "name":{
     "description":"Name of the product",
     "required":true
   },
   "price":{
     "required":true,
     "type": "number",
     "minimum":0,
     "required":true
   }
 },
 "extends": {
     "type":"any"
 }
}

{
 "name":"Product",
 "type":["object","any"],
 "properties":{
   "id":{
     "type":"number",
     "required":true
   },
   "name":{
     "description":"Name of the product",
     "required":true
   },
   "price":{
     "required":true,
     "type": "number",
     "minimum":0,
     "required":true
   }
 }
}

さらにいくつか(「any」と「object」の役割を逆にするなど)を思いつくことができますが、これらはすべてこれら3つの例から派生したものです。

17
Bernardo Cunha

[免責事項:次のJSONスキーマ検証仕様の作成者はこちら]

わかりました、あなたが何を尋ねるかは不明です、以下を見てください、しかしあなたの例の1つは明らかにあなたが望むことをしません、これはあなたが書くものです:

{ "type": [ "object", "any" ] }

これは空のスキーマと同等であり、そのため、すべてのインスタンスを検証します。

私があなたの質問を読む1つの方法は、JSONデータをタグ配列にするか、少なくともidname、およびpriceという名前のメンバーを持つオブジェクトにすることです。ドラフトv3を使用しているように見えるため、解決策は1つだけです。

{
    "type": [
        {
            "description": "schema for tags array here",
        },
        {
            "description": "schema for the base object here"
        }
    ]
}

この構成は、インスタンスがtype内の少なくとも1つのスキーマに従う必要があることを意味します(プリミティブ型と混合することもできます)。

ただし:現在のドラフトはv4になっているので、次のように書く必要があります。

{
    "anyOf": [
        {
            "description": "schema for tags array here",
        },
        {
            "description": "schema for the base object here"
        }
    ]
}

すべての実装がドラフトv4、または上記のtypeの構成をサポートしているわけではないことに注意してください。実際、そうする人はほとんどいません。両方をサポートするオンラインスキーマバリデーターへのリンクについては、以下を参照してください。

私があなたの質問を読んだ別の方法は、idname、およびprice以外のプロパティを好きなように許可したいということです。これは非常に簡単です。 tagspropertiesのスキーマを定義しないでください。

{
    "type": "object",
    "required": [ "id", "name", "price" ]
    "properties": {
        "id": {
            "type": "number"
        },
        "name": {
            "description": "Name of the product"
        },
        "price": {
            "type": "number",
            "minimum": 0
        }
    }
}

additionalPropertiesfalseとして指定しないため、オブジェクトインスタンスには任意の数の追加メンバーを含めることができ、これらのメンバーは何でもかまいません。

スキーマをテストできるオンラインバリデーターへのリンク: ここ

35
fge