Home > OS >  JSON Schema construction for a objects with. common properties but differing in some properties
JSON Schema construction for a objects with. common properties but differing in some properties

Time:07-15

I have a a number of objects which share a common set of features but differ in one or more properties. The common content is specified as media content in the definitions. I have provided one such object with a 'format' property, but there are other objects, omitted to keep it short, that also have additional properties. Here is a snippet of my attempt at constructing the schema. Is this the correct way to accomplish, this? Many thanks

 "definitions": {
 "media-content":{
  "type": "object",
  "title": {
    "type": "string"
  },
  "related-media": {
    "type": "object",
    "additionalProperties": {
      "type": "string"
    }
  }
 },

 "type": "object",
 "properties": {
    "type": {
        "format": "string",
        "enum":["audio", "video"]
    },
    "category": {
        "$ref": "#/definitions/media-content"
    }             
 }

Is this the way to do it?

CodePudding user response:

The first thing that stands out to me is that this isn't valid JSON Schema.

The title keyword provides a title for the schema so it expects a string, but because you've provided a schema, it looks like you're wanting it to be a property. Similarly related-media looks like you expect this to be a property. Are you missing wrapping these in a properties keyword, like you have later for type and category?

These changes would make media-content look like this:

"media-content":{
  "type": "object",
  "properties": {
    "title": {
      "type": "string"
    },
    "related-media": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    }
  }
}

I have provided one such object with a 'format' property

Again, here, I'm not sure what you're getting at.

"properties": {
    "type": {
        "format": "string",
        "enum":["audio", "video"]
    },
    "category": {
        "$ref": "#/definitions/media-content"
    }             
 }

This says you're expecting type to be a property in your object, but format isn't used right. Although the format keyword has some predefined types and does accept custom values, the way you're using it look like you really want to be using the type keyword. In the end, it doesn't matter because enum will restrict the value to the items you declare in the array ("audio" or "video").

It might be easier to see what you're trying to do if you posted a full minimum exaple.

That said, I'll try to build one to answer the question I think you're asking.


It sounds like you're wanting to build a polymorphic relationship: an inheritance hierarchy where a base type defines some properties and a number of derived types define additional properties.

There's not really a good way to do that with JSON Schema because JSON Schema is a constraints system. That is, you start with {} where anything is valid, and by adding keywords, you're reducing the number of values that are valid.

Still, you might be able to achieve something close by using allOf and $ref.

First, declare the base property set in its own schema. I'd separate them into independent schemas for easier handling. You also need to give it an $id.

{
  "$id": "/base-type"
  "type": "object",
  "properties": {
    "base-prop-1": { "type": "string" },
    "base-prop-2": { "type": "number" }
  }
}

Next, for each of your "derived" schemas, you'll want to create a new schema, each with their own $id value, that references the base schema and declares its own additional requirements.

{
  "$id": "/derived-type-1",
  "allOf": [
    { "$ref": "/base-type" },
    {
      "properties": {
        "derived-prop": { "type": "boolean" }
      }
    }
  ]
}

This second schema requires everything from the /base-type and also requires a derived-prop property that holds a boolean value.

  • Related