Adam Bielecki
Adam Bielecki

Reputation: 697

Add pattern validation in json schema when property is present

Below is my schema definition and I would like to add pattern that depends on environment propertyName (env1, env2 or env3). Each env should have different pattern. For instance when env1 is present then url will have a different pattern than when env2 is present etc.

{
  "environments": {
    "env1": {
      "defaultAccess": {
        "url": [
          "something-staging"
        ]
      }
    }
  }
}

My current schema definition for that example

    {
    "$schema": "https://json-schema.org/draft-07/schema#",
    "definitions": {
        "envType": {
            "type": "object",
            "properties": {

                "defaultAccess": {
                    "type": "object",
                    "properties": {
                        "url": {
                            "type": "string",
                            "pattern": "^[a-zA-Z0-9- \/]*$"

                        }
                    },
                    "required": [
                        "url"
                    ]
                }
            }
        },
        "environmentTypes": {
            "type": "object",
            "properties": {
                "env1": {
                    "$ref": "#/definitions/envType"

                },
                "env2": {
                    "$ref": "#/definitions/envType"
                },
                "env3": {
                    "$ref": "#/definitions/envType"
                }
            }
        },

        "type": "object",
        "properties": {
            "environments": {
                "$ref": "#/definitions/environmentTypes"
            }
        }
    }
}

In my head I have something like this but do not know how to apply it to the schema properly.

{
      "if": {
        "properties": {
          "environments": {
            "env1" : {}
          }
        }
      },
      "then":{
        "properties": {
          "environments-env1-defaultAccess-url" : { "pattern": "^((?!-env2).)*$" }
        }
      }
    }

etc..

Upvotes: 0

Views: 837

Answers (1)

Jason Desrosiers
Jason Desrosiers

Reputation: 24399

If understand correctly what you're trying to do, you shouldn't need conditionals for this kind of thing.

You have an error in your schema that might be tripping you up. You have your main schema inside the definitions keyword. If you run this through a validator, you should get an error saying that the value a /definitions/type must be an object.

Aside from that, schema composition using allOf should do the trick. Below, I've shown an example at /definitions/env1Type.

It looks like you were hoping for a less verbose way to specify a schema deep in an object structure (""). Unfortunately, there's no way around having to chain the properties keyword all the way down like I've demonstrated at /definitions/env1Type.

{
  "$schema": "https://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "environments": { "$ref": "#/definitions/environmentTypes" }
  },
  "definitions": {
    "environmentTypes": {
      "type": "object",
      "properties": {
        "env1": { "$ref": "#/definitions/env1Type" },
        "env2": { "$ref": "#/definitions/env2Type" },
        "env3": { "$ref": "#/definitions/env3Type" }
      }
    },
    "envType": { ... },
    "env1Type": {
      "allOf": [{ "$ref": "#/definitions/envType" }],
      "properties": {
        "defaultAccess": {
          "properties": {
            "url": { "pattern": "^((?!-env1).)*$" }
          }
        }
      }
    },
    "env2Type": { ... },
    "env3Type": { ... }
  }
}

Upvotes: 1

Related Questions