json-schema-org / json-schema-spec

The JSON Schema specification

Home Page:http://json-schema.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why does draft 7 sometimes use `format: regex` without `type: string`?

ahl opened this issue · comments

The use of regex as a format seems inconsistent:

with type

"pattern": {
"type": "string",
"format": "regex"
},

without type

"propertyNames": { "format": "regex" },

Is "type": "string" optional in this case? If so, why does the former case include it? If not, is the latter case a bug?

Thanks.

commented

At least the current draft section 7.1 says

A format attribute can generally only validate a given set of instance types. If the type of the instance to validate is not in this set, validation for this format attribute and instance SHOULD succeed.

Which means

{ "format": "regex" } will allow the types int, number, null, array, boolean and object. Only if the type is string and the format is not a regex it will yield false.

Not sure if this behavior was different in past drafts (I guess not), so I would say a {"type": "string"} is missing here.

Side note: This behavior is imminent to many if not all jsonschema attributes. Because of this the (hypothetical) format-wise negation ("a format which is not a regex"), is not just a simple "not" around "format", but actually requires the type to be included: {"format": "non-regex"} <=> {"not": { "format": "regex", "type": "string" }

There are some reasons you might want to leave out "type": "string". In the example given, the schema is used with the propertyNames keyword. Property names in a JSON object are always strings. They can't be anything else. Therefore, including "type": "string" is superfluous.

Another reason you might want to leave out "type": "string" is when doing schema composition. Here's an example.

{
  "type": "string",
  "allOf": [
    { "pattern": "^a" },
    { "pattern": "b$" }
  ]
}

Here, the schemas with pattern don't need "type": "string" because "type": "string"` has already been applied to the instance.

There are some reasons you might want to leave out "type": "string". In the example given, the schema is used with the propertyNames keyword. Property names in a JSON object are always strings. They can't be anything else. Therefore, including "type": "string" is superfluous.

This is a great point. Thank you!