1
votes

I'm trying to write a JSON schema for my JSON object and I'm not able to follow the error. I want my JSON object to be stored in the following manner in Java:

public class Category {
   private Map<String, List<String>> categoryMapping;
}

Sample JSON:

{
  "categoryMapping": {
    "categoryA": ["a","b","c"],
    "categoryB": ["x","y","z"],
    "categoryC": ["x","y","z"]
  }
}

However if I write the schema in the following way:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "title": "$id$",
  "description": "list_of_values-1",
  "required": [
    "categoryMapping"
  ],
  "properties": {
    "categoryMapping": {
      "$id": "#/properties/categoryMapping",
      "type": "object",
      "title": "The categoryMapping Schema",
      "properties": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
    }
  }
}

I get the following error: The property '#/properties/categoryMapping/properties/type' of type String did not match the following type: object in schema http://json-schema.org/draft-04/schema#

But if I specify the types of categories it works:

"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"title": "$id$",
"description": "list_of_values-1",
"properties": {
    "categoryMapping": {
      "$id": "#/properties/categoryMapping",
      "type": "object",
      "title": "The Categorymapping Schema",
      "required": [
        "categoryA",
        "categoryB",
        "categoryC"
      ],
      "properties": {
        "categoryA": {
          "$id": "#/properties/categoryMapping/properties/categoryA",
          "type": "array",
          "title": "The Categorya Schema",
          "items": {
            "$id": "#/properties/categoryMapping/properties/categoryA/items",
            "type": "string",
            "title": "The Items Schema",
            "default": "",
            "examples": [
              "a",
              "b",
              "c"
            ],
            "pattern": "^(.*)$"
          }
        },
        "categoryB": {
          "$id": "#/properties/categoryMapping/properties/categoryB",
          "type": "array",
          "title": "The Categoryb Schema",
          "items": {
            "$id": "#/properties/categoryMapping/properties/categoryB/items",
            "type": "string",
            "title": "The Items Schema",
            "default": "",
            "examples": [
              "x",
              "y",
              "z"
            ],
            "pattern": "^(.*)$"
          }
        },
        "categoryC": {
          "$id": "#/properties/categoryMapping/properties/categoryC",
          "type": "array",
          "title": "The Categoryc Schema",
          "items": {
            "$id": "#/properties/categoryMapping/properties/categoryC/items",
            "type": "string",
            "title": "The Items Schema",
            "default": "",
            "examples": [
              "x",
              "y",
              "z"
            ],
            "pattern": "^(.*)$"
          }
        }
      }
    }
  }
}

Is there a way to write the schema without explicitly specifying a list of all category types?

1

1 Answers

1
votes

So your sample JSON is actually a type with three properties, which is why the schema you have generated requires you to define each property explicitly, even though they are effectively of the same type.

If you were willing to modify your sample json a little bit, however:

{
  "categoryMapping": [
    {
      "name": "categoryA",
      "map": ["a","b","c"]
    },
    {
      "name": "categoryB",
      "map": ["x","y","z"]
    },
    {
      "name": "categoryC",
      "map": ["x","y","z"]
    }
  ]
}

Then you could validate it with the following schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "categoryMapping": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "map"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "map": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}

Because you can specify the minimum and maximum number of items allowed in an array, you could restrict the number of categories to 3 and the number of "maps" to 3 also if you wanted to.