Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reuse pattern in JSON schema

Is it possible to define a regex once and re-use it? I have a few pretty complex regexes which I would like to use as the pattern for the value of a large number of properties of various different object in my schema. Doing Copy paste of this looks like asking for trouble further down the line, but I can't seem to find a suitable re-use example anywhere.

Cut down schema which illustrates what I want to do.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "patterns": {
    "fqdn_or_ipaddress": "(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\\.)+[a-zA-Z]{2,63}$)||(((?:^[0-9])(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))(?![0-9])$)|(^\\*$))",
  },
  "properties": {
    "server_hostname" : {
       "type":"string",
       "pattern": {"#ref", "#/patterns/address"},
    },
    "proxy_hostname" : {
       "type":"string",
       "pattern": {"#ref", "#/patterns/address"},
    }   
  }
}

Doesn't validate here http://www.jsonschemavalidator.net/ because "pattern" is not a string. Is this a hole in the re-use. I've looked at patternProperties, but that seems to solve completely different use case.

like image 858
smcp Avatar asked Jun 26 '17 10:06

smcp


1 Answers

You can only $ref a schema. You would need to do something like this.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "server_hostname" : {
      "$ref": "#/definitions/fqdn_or_ipaddress",
      "description": "The server hostname"
    },
    "proxy_hostname" : {
      "allOf": [{ "$ref": "#/definitions/fqdn_or_ipaddress" }],
      "description": "The proxy hostname"
    }
  },
  "definitions": {
    "fqdn_or_ipaddress": {
      "type": "string",
      "pattern": "(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\\.)+[a-zA-Z]{2,63}$)||(((?:^[0-9])(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))(?![0-9])$)|(^\\*$))"
    }
  }
}

EDIT

I added two examples of how to extend from a $ref. In the first, you can just add the description. It will be ignored, but it is not an error. Since description is just a meta-data keyword, this shouldn't be a problem.

In the second example, you can use allOf to wrap the $ref and you can add whatever keywords you need (even non-meta data keywords).

like image 160
Jason Desrosiers Avatar answered Nov 28 '22 10:11

Jason Desrosiers