In what I can find about using JSON schema, there seems to be a confusing conflation of (or at least a lack of distinction among) the tasks of describing valid data, validating stored data, and validating input data.
A typical example looks like:
var schema = {
type: 'object',
properties: {
id: { type: 'integer', required: true },
name: { type: 'string', required: true },
description: { type: 'string', required: false }
}
};
This works well for describing what valid data in a data store should look like, and therefore for validating it (the latter isn't terribly useful—if it's in a store it should be valid already):
var storedData = {
id: 123,
name: 'orange',
description: 'delicious'
};
It doesn't work that well for validating input. id
is most likely left for the application to generate and not for the user to provide as part of the input. The following input fails validation because it lacks the id
which the schema declares to be required
:
var inputData = {
name: 'orange',
description: 'delicious'
};
Fine, one might say, the schema isn't meant to validate direct input, validation should only occur after the application added an id
and the data is what is meant to be stored.
If the schema isn't meant to validate direct input, however, what is 1) the point of JavaScript validators running in the browser, presumably being fed direct input and 2) the point of the obviously input-oriented readonly
schema feature in the spec?
Ground gets shakier when thinking of properties that can be set once but not updated (like a username), as well as different access levels (e.g. the admin and the owner of the orange should be able to change the description
, while for other users it should stay readonly
).
What is the best (or at least working) practice to deal with this? A different schema for each use case, like below?
var baseSchema = {
type: 'object',
properties: {
id: { type: 'integer', required: true },
name: { type: 'string', required: true },
description: { type: 'string', required: false }
}
};
var ownerUpdateSchema = {
type: 'object',
properties: {
id: { type: 'integer', required: false, readonly: true },
name: { type: 'string', required: true },
description: { type: 'string', required: false }
}
};
var userUpdateSchema = {
type: 'object',
properties: {
id: { type: 'integer', required: false, readonly: true },
name: { type: 'string', required: false, readonly: true },
description: { type: 'string', required: false, readonly: true }
}
};
Or something else?