Make sure the property of the element in the array is unique in the Json schema?

Given the following JSON schema, is it possible to specify that the "name" property should be unique (ie, the array "elements" should NOT have two elements with the same "name".

{
  "root": {
    "type": "object",
    "properties": {
      "elements": {
        "type": "array",
        "minItems": 1,
        "items": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "title": "Element Name",
              "minLength": 3,
            },
            "url": {
              "type": "string",
              "title": "Some URL"
            }
          }
        }
      }
    }
  }
}

      

I tried to use the uniqueItems keyword , but it looks like it was designed for simple lists of values.

+24


source to share


3 answers


No, It is Immpossible. From the json-schema documentation: ... JSON format to define the JSON data structure.

This is rather limited for data validation as it is not the intent of the standard. Many people have asked this before because it is usually a kind of "unique ID" that is requested. Unfortunately for those who need it, json-schema doesn't provide this for you.



So, if you want to enforce uniqueness, your only option is to have "name" as property keys instead of property values.

+23


source


If refactoring the data structure is an option, the following approach might be helpful:

  • Replace array with map. This can be easily achieved using the object with patternProperties

    . The pattern is a regular expression. Any object matching the pattern will be checked against the pattern of the pattern property. A pattern matching any string> = 3 characters looks like this: "....*"

    but it seems like it always has a trailing value ".*"

    , so it "..."

    works.
  • Adding additional properties: false is an extra step to enforce your constraint ( minLength:3

    ).
  • To provide at least one element in your map (you used minItems:1

    for your array), replace minItems

    with minProperties

    .

... results in the following pattern:

"root": {
  "type": "object", 
  "properties": {
    "elements": {
      "type": "object", 
      "patternProperties": {
        "...": {
          "type": "object", 
          "properties": {
            "url": {
              "type": "string"
            }
          }
        }
      }, 
      "additionalProperties": false, 
      "minProperties": 1
    }
  }
}

      



If a document like the following (excerpt) follows your old scheme,

"elements": [
  {
    "name": "abc", 
    "url": "http://myurl1"
  }, 
  {
    "name": "def", 
    "url": "http://myurl2"
  }, 
  {
    "name": "ghij", 
    "url": "http://myurlx"
  }
]

      

... such a document (excerpt) would follow the new schema:

"elements": {
  "abc": {
    "url": "http://myurl1"
  }, 
  "def": {
    "url": "http://myurl2"
  }, 
  "ghij": {
    "url": "http://myurlx"
  }
}

      

+7


source


If your use case can handle the additional overhead, you can apply the transform to the document to create the shorthand document, and then reapply the validation with a separate mini-diagram to the shortcut document.

Here are some links with information on Json conversion tools:

Handling your example will be very easy in JSONata.

+1


source







All Articles