-
-
Notifications
You must be signed in to change notification settings - Fork 215
Explain why inheritance isn't the right model #148
Comments
Might as well bring the comment over. The rest of this was not written by me: JSON Schema doesn't support inheritance. You can combine schemas using boolean operations in ways that can look like inheritance, but if you think about it that way, you will confuse what is actually happening. You will have to get out of that mindset and think about defining your data a little differently. Your example is a fairly easy one to express except for one thing. I'll start with the schemas and then explain what it's doing and what the limitations are. {
"id": "http://example.com/schemas/person",
"type": "object",
"properties": {
"firstName": { "type": "string" },
"lastName": { "type": "string" }
},
"required": ["firstName", "lastName"]
} {
"id": "http://example.com/schema/employee",
"allOf": [{ "$ref": "http://example.com/schemas/person" }],
"properties": {
"company": { "type": "string" }
},
"required": ["company"]
} In the Employee schema, we use {
"type": "object",
"allOf": [
{
"properties": {
"foo": { "type": "integer", "minimum": 2 }
}
}
{
"properties": {
"foo": { "type": "integer", "multipleOf": 2 }
}
}
]
} In this example the property "foo" has a minimum of 2 and excludes odd numbers. The limitation you have with this approach is that you can't use {
"id": "http://example.com/schema/final-employee",
"allOf": [
{ "$ref": "http://example.com/schemas/person" },
{ "$ref": "http://example.com/schemas/employee" }
],
"properties": {
"firstName": {},
"lastName": {},
"company": {}
},
"additionalProperties": false
} The problem, of course, is that any time you add a property to either of these schemas, you need update FinalEmployee as well. That's why I advise that you always ignore additional properties rather than explicitly forbid them. It has some value, but not nearly enough to be worth the pain. So, I hope that helped. Schemas are not describing objects, they are a collection of constraints. So, thinking in terms of inheritance doesn't work. |
Another good explanation is given in the "Understanding JSON Schema" book:
|
What's a best practice if you are used to thinking in terms of inheritance? How should I approach this from a design perspective? |
@PaulCezanneFMR that's a good question. I think it depends on what you're trying to get out of JSON Schema. The Validation vocabulary is not really ideal for code generation tools, for instance. In particular, mimicking strongly typed language behavior typically requires making everything Also, draft-08 is focusing on modularity and re-usability, so we may add features or develop recommendations to support something more like OO inheritance, although the topic is extremely divisive so I'm really not sure how that will play out. |
I agree JSON Schema is currently unsuitable as a clear means to define type inheritance, but the reasoning here is flawed. This statement in particular captures the general misconception presented here:
Well... not really. This is a gross oversimplification of what a JSON Schema really is and what it is used for. It is far more than a set of constraints. Essentially it serves three primary functions:
The focus here is on 1 -- a JSON Schema as a means to model structured data. Yes, it also provides constraints on the model, but that does not somehow excuse it from properly modeling inheritance -- it just doesn't provide a clear way to express it (yet). That said, Cheers. |
It's pretty bold to argue that the primary maintainer of the JSON Specification (@handrews) misunderstands "what JSON Schema really is and what it is used for". But, I've been known to make that argument as well, so 🤷♂️. JSON Schema really has two primary functions: validation and hypermedia. The specification reflects this by the way it's divided into parts: core, validation, and hyper-schema. These are the only things JSON Schema is designed for. People have attempted to use JSON Schema in many unsupported ways including data modeling, documentation, and form building. I believe that the misconception that data modeling is a primary function of JSON Schema comes from Open API who has co-opted JSON Schema for that purpose. JSON Schema is a poor enough fit for this purpose that Open API had to define their own custom version of JSON Schema for their purposes. Using JSON Schema for something other than validation or hypermedia is not a bad thing, but it will always be trying to fit a square peg into a round hole. You're trying to extract additional meaning out of an unordered declarative bag of constraints.
The specification is not ambiguous in this respect. However, there is hope for those who want to use JSON Schema for things other than validation or hypermedia. A new JSON Schema concept called "vocabularies" is in the works. Vocabularies will (in theory) allow the definition of new keyword sets that are designed for things like data modeling, documentation, form building, or whatever else people want to use it for. Finally, I suggest taking this conversation to the JSON Schema slack. It's a better forum for this kind of conversation and you'll get more people to weigh in on whether they are for or against your point of view. |
Thanks for the info. Maybe I'll move this to slack as you suggest, thanks. |
Whenever we get to topic guides, here, @jdesrosiers wrote an excellent answer to the question of inheritance, ending with the great quote
This would be a good basis for an explanatory article, I think.
The text was updated successfully, but these errors were encountered: