Search code examples
jsonschema

How to inject a constraint into a $ref object in jsonSchema


Consider the following snippet of jsonSchema

"properties": {
    "custom-range": {
        "$ref": "#/$defs/minMax",
        "description": "Custom range of allowable values",
    }
},

with the $defs section being...

"$defs": {
    "minMax": {
        "type": "object",
        "properties": {
            "min": {
                "type": "number",
                "description": "Minimum value"
            },
            "max": {
                "type": "number",
                "description": "Maximum value"
            }
        }
    }
}

Is there a way to restrict instance/values of the "custom-range" instances of minMax.min and minMax.max?

So for example I would like to restrict minMax.min with "minimum":20,"maximum":30 for the "custom-range" instance of that object.

ANSWER: Thank you user gregsdennis

The solution that seems to work is as follows

"properties": {
    "custom-range": {
        "$ref": "#/$defs/minMax",
        "description": "Custom range of allowable values",
        "properties": {
            "min": {
                "minimum": 20,
                "maximum": 30
            }
        }
    }
},

When used as the schema for a jsonschema command line validator, I was able to get a message of "100.0: 100.0 is greater than the maximum of 30"


Solution

  • I think your best bet is to define a subschema that just declares the min/max values, and then combine that with a $ref to the definition in an allOf.

    "properties": {
      "custom-range": {
        "allOf": [
          { "$ref": "#/$defs/minMax" },
          {
            "properties": {
              "min": { "minimum": 20 },
              "max": { "maximum": 50 }
            }
          }
        ]
      },
      "custom-range-2": {
        "allOf": [
          { "$ref": "#/$defs/minMax" },
          {
            "properties": {
              "min": { "minimum": -5 },
              "max": { "maximum": 100 }
            }
          }
        ]
      }
    }
    

    This works because JSON Schema is just a bunch of constraints. The $ref to the minMax definition ensures that you have an object with the appropriate properties, and the secondary subschema in the allOf simply adds more requirements to those same properties.

    It's not "injecting" the values into the definition so much as adding the constraints alongside the definition.