Search code examples
jsonjsonschemajson-schema-validatorajv

JSON schema validator - validate one property based on another property in different part of schema


I have open api schema in which I want to validate that

  1. If the oauth2 flow in the components section contains the tokenUrl in string format then url in the servers section should have https: in the url value.
  2. If the tokenUrl is not present then it should do nothing

is there any way this is possible with JSON schema validator?

Below is the schema for reference

{  
    "servers": [
        {
            "url": "http://my.api.server.com/",
            "description": "API server"
        }
    ], 
    "components": {
        "securitySchemes": {
            "OAuth2": {
                "type": "oauth2",
                "flows": {
                    "authorizationCode": {
                        "scopes": {
                            "write": "modify objects in your account",
                            "read": "read objects in your account"
                        },
                        "authorizationUrl": "https://example.com/oauth/authorize",
                        "tokenUrl": "https://example.com/oauth/token" 
                    }
                }
            }
        }
    },
    "security": [
        {
        "OAuth2": [
                "write",
                "read"
            ]
        }
    ]
}

Solution

  • I have found a way to achieve this type of validation. Below is the schema that helps you validate the same

    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "servers": {},
        "components": {}
      },
      "if": {
        "properties": {
          "components": {
            "properties": {
              "securitySchemes": {
                "type": "object",
                "patternProperties": {
                  "^[a-zA-Z0-9\\.\\-_]+$": {
                    "type": "object",
                    "properties": {
                      "flows": {
                        "type": "object",
                        "properties": {
                          "tokenUrl": {
                            "const": true
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "then": {
        "type": "object",
        "properties": {
          "servers": {
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "type": "string",
                  "pattern": "https://"
                }
              }
            }
          }
        }
      }
    }
    

    if - then is used to set up conditional relation between components tokenUrl property and servers url property. Here

    {
        "tokenUrl": {
            "const": true
        }
    }
    

    means that tokenUrl should be present in the components object, then whatever rule is defined in then blocks takes effect. Here below schema will validate the url pattern to be https only

    {
        "url": {
            "type": "string",
            "pattern": "https://"
        }
    }