choices (v5 proposal to enhance enum) - sgpinkus/json-schema GitHub Wiki
JSON-SCHEMA-ORG/JSON-SCHEMA-SPEC REPOSITORY.
THIS WIKI IS OBSOLETE. PLEASE SEE THE NEWNOTE: This proposal has been migrated to https://github.com/json-schema-org/json-schema-spec/issues/57
Problem
the enum
attribute for strings is really useful but has a severe limitation: it does not support providing a human readable label for raw values.
I tried workaround solutions but I prefer to stick to enum
for its simplicity and for the fact that UI implementations (like JSON Editor) can very easily generate an HTML select with the allowed values.
Unfortunately though, enum
cannot provide human readable values for decoration and documentation purposes (just like title
and description
properties included in the json-schema validation RFC), which makes it difficult to work with a long list of raw values that differ greatly from the corresponding human readable ones, for example, in a list of timezone settings for the entire globe, how can a programmer remember that "SAST-2" means "Africa/Mbabane" and "MST7MDT,M3.2.0,M11.1.0" means "America/Cambridge Bay".
The human readable value can be used for different purposes:
- decoration
- documentation
- UI generation
- validation error message generation
Solution proposed
Many popular frameworks like Django (python), Ruby on Rails (ruby) and Symfony (php) support specifying a list of choices
, which are usually either a list of tuples or a dictionary (associative array), in which one element is the raw value while the other is the corresponding human readable label.
An example of a subset of choices for timezones:
[
["UTC", "Coordinated Universal Time"],
["GMT0", "Africa/Abidjan"],
["GMT0", "Africa/Accra"],
["EAT-3", "Africa/Addis Ababa"],
["WAT-1", "Africa/Bangui"]
]
Backward compatibility
Adding a "choices" (or an equivalent) attribute can be backward compatible with the current draft (v4):
if both enum
and choices
would be present, choices
would be used.
if only enum
is present implementations can still support it for backward compatibility.
Full backward compatible example:
{
enum: ["UTC", "GMT0", "EAT-3"],
choices: [
["UTC", "Coordinated Universal Time"],
["GMT0", "Africa/Abidjan"],
["EAT-3", "Africa/Addis Ababa"],
]
}
Advantages
Using a list of tuples (opposed as a list of objects) has the advantage of being a very simple, portable, and concise.
It's easier to maintain, faster to type and easier to read. Additional attributes can be allowed from the third element onwards if needed.
Another advantage is that this pattern is very well known in many MVC frameworks and it will result familiar to a lot of developers.
Downsides
The main downside is duplication of efforts when backward compatibility is needed: In an eventual transition from v4 to v5 both enum
and choices
should be supported in implementations. Popular schemas that aim to maximum compatibility also should use both.