Comments (18)
Just to give a little more clarity, here's a more involved example. The following is a schema for a network interface where interface
and dhcp
are required, but if dhcp
is set to true then we also require ip
, mask
, and gw
:
{
type: 'object',
anyOf: [
{
properties: {
interface: { type: 'string' },
dhcp: { constant: false },
ip: { type: 'string', format: 'ipv4' },
mask: { type: 'string', format: 'ipv4' },
gw: { type: 'string', format: 'ipv4' }
},
required: [ 'hostid', 'interface', 'dhcp', 'ip', 'mask', 'gw']
}, {
properties: {
interface: { type: 'string' },
dhcp: { constant: true },
ip: { anyOf: [ {type: 'string', format: 'ipv4'}, { type: 'null' } ] },
mask: { anyOf: [ {type: 'string', format: 'ipv4'}, { type: 'null' } ] },
gw: { anyOf: [ {type: 'string', format: 'ipv4'}, { type: 'null' } ] }
},
required: [ 'hostid', 'interface', 'dhcp' ]
}
]
}
when with joi I could do something like:
{
interface: Joi.string().required(),
dhcp: Joi.boolean().required(),
ip: Joi.string().ip().when('dhcp', { is: false, then: Joi.required() }),
mask: Joi.string().ip().when('dhcp', { is: false, then: Joi.required() }),
gw: Joi.string().ip().when('dhcp', { is: false, then: Joi.required() })
}
which is not only more compact, but I feel is also very fluent compared to the json-schema version
from json-schema-spec.
ah, looks like we might be able to tackle this already with switch
(https://github.com/json-schema/json-schema/wiki/switch-(v5-proposal))
from json-schema-spec.
@mbroadst Can you compare and contrast this issue to my earlier #31?
This isn't a terrible example, but these sorts of complex rules tend to be overthought. In particular, I would suggest this may be a bit contrived, and I wouldn't use JSON Schema to specify "if DHCP is false, then IP is required": Consider what happens if there is no DHCP server, it's the exact same failure condition (except for the fact we can prove the failure ahead of time, ignoring link-local and stateless-autoconfiguration addresses.) Generally, JSON Schema is not intended to be the end-all-be-all of what data is acceptable and what isn't, especially things like relational data/foreign key constraints (though there might be a way to do that, but I don't think it would be appropriate for the JSON Schema validation vocabulary, maybe a different one like JSON Hyper-schema).
Further, you can simplify your example:
{
type: 'object',
properties: {
"interface": { type: 'string' },
"dhcp": { type: 'boolean' },
"ip": { type: 'string', format: 'ipv4' },
"mask": { type: 'string', format: 'ipv4' },
"gw": { type: 'string', format: 'ipv4' }
},
required: [ 'hostid', 'interface', 'dhcp' ],
oneOf: [
{ properties: { "dhcp": { enum: [false] } }, required: ['ip', 'mask', 'gw'] },
{ properties: { "dhcp": { enum: [true] } } }
]
}
from json-schema-spec.
So I implemented this with switch like so:
{
type: 'object',
properties: {
interface: { type: 'string' },
dhcp: { type: 'boolean' },
ip: { type: 'string', format: 'ipv4' },
mask: { type: 'string', format: 'ipv4' },
gw: { type: 'string', format: 'ipv4' }
},
required: [ 'hostid', 'interface', 'dhcp' ],
switch: [{
if: { properties: { dhcp: { constant: false } } },
then: { required: [ 'ip', 'mask', 'gw' ]}
}]
}
which is similar to your proposed cleanup with oneOf
. I also agree that your previous issue essentially addresses the main point of this issue
Having said that, I'm not sure I agree with your assessment over on that issue: how would this be considered a misuse of json-schema? While it does introduce complexity to the validation process, I feel like this is a far more readable format for acceptable data than having to provide multiple almost duplicate schemas (perhaps with a single property changed).
You mention that:
Generally, JSON Schema is not intended to be the end-all-be-all of what data is acceptable and what isn't
so perhaps you can clarify what json-schema is intended to be 😄 Because if I go down the list of proposed features of the spec, I find this is completely in line:
- "describes your existing data format" ✔️
- "clear, human- and machine-readable documentation" ✔️ (far more readable than the alternative
anyOf
above) - "complete structural validation" ✔️
from json-schema-spec.
With regard to this example with IP addresses in particular, I'm not quite sure that this is structural validation.
JSON Schema (by which I mean, the default JSON Schema profile, as opposed to JSON Hyper-schema or any future profiles) doesn't intend to do things like integrate errors from external data sources (like "that user ID does not exist" or "that IP address is already in use").
(Maybe with an extension, this might be assertable, but that's outside the scope of structural validation.)
What happens if the DHCP server never issues an IP address, which error does that produce? Why can't failing to provide an IP address if dhcp=false be the same error, instead of a structural error? So then what's the benefit of making this a structural requirement?
Even if this example is totally bogus, switch
might still be a good idea. The thing in general I'm worried about is that the more expressive something becomes, the harder it is to reason about.
from json-schema-spec.
@awwright perhaps I should have been more clear in my initial comment here, but I don't consider this example to be bogus at all. This is a schema I'm considering using for form validation of network interface configuration. I had mentioned it was contrived mostly to indicate that it was reduced from its original form to express the issue I required switch
for, as well as not optimizing it at all.
There is no external data integrated here, nobody issues us an IP address other than the user of the form. The reason to require those fields when dhcp
is false
should be more clear in this case. HTH
from json-schema-spec.
I'm not implying it is; there's one thing I'm getting at though... What kind of error is it if DHCP fails and there's no static IP address listed?
Why should no static address with dhcp=false be any different?
from json-schema-spec.
Could you clarify what "DHCP fails" means in this context? Do you mean if validation fails for that property?
from json-schema-spec.
The client, because it's configured to use DHCP, sends out a DHCP request but doesn't get a response, and there's no configured static IP address either.
I'm trying to get to the root of what structural validation means here.
from json-schema-spec.
I apologize, maybe it's just been a while since we originally discussed this but I'm just not following what you're saying. Also, I'm not sure we're coming to any further truths about the world here 😄 switch
and oneOf
both satisfy my use case, so I think we can call this one finished
from json-schema-spec.
There's no need to close this, this is a real issue, and I'm trying to track down a realistic use-case.
I do need to understand what you're getting at with your example, though, and how it works in the bigger picture (JSON Schema, after all, doesn't actually perform any tasks, it has to be used as part of something that does).
You've provided a simple JSON Schema for configuring a network interface. Someone configures a network interface with an instance of this schema. Now suppose I configure with {"interface":"eth0", "dhcp":true}
but the interface never acquires an IP address from a DHCP server. What kind of error is that?
from json-schema-spec.
{"interface":"eth0", "dhcp":true}
=> error that hostid
isn't provided
other examples:
{"interface":"eth0", "hostid": "something", "dhcp":true}
=> no error
{"interface":"eth0", "hostid": "something", "dhcp":false}
=> error because no ip information was provided
{"interface":"eth0", "hostid": "something", "dhcp":false, "ip": "192.168.1.10"}
=> error because gw, mask are omitted
{"interface":"eth0", "hostid": "something", "dhcp":false, "ip": "192.168.1.10", "mask": "255.255.255.0", "gw": "192.168.1.1" }
=> no error
You've provided a simple JSON Schema for configuring a network interface.
Specifically, I'm providing a schema for a configuration file for a network interface. This schema, in my example, will be used to validate a web form of that data before passing it along to a rest api which will eventually save it to disk. To that end, a discussion about what happens to that interface outside the scope of configuring that interface (it makes DHCP requests, the requests are ignored, etc) seems to me to be confusing the discussion here - or I think I'm unfortunately completely missing what you're driving at.
Could you also please provide your definition of structural validation
? A google search results in tons of links to sites on atomic modeling, I don't think that's what you're talking about here 😄
from json-schema-spec.
@awwright : It sounds like you're concerned about JSON Schema being used to verify runtime behavior, which I (and I think based on his last comment, @mbroadst ) agree is outside of JSON Schema's scope.
However, using it to validate that, based on the value of one field in a particular JSON representation of a resource, the rest of the resource at least defines a potentially valid configuration is a good use case, and one that we used at Riverbed when I worked there. Specifically, this service definition (a collection of json-schema for resources in a given service) uses it in the schema for "vlan_tag":
Riverbed SteelHead Common Type Definitions Service
The relevant portion (in YAML for readablity) is:
vlan_tag:
description: 'VLAN tag (all, untagged, tagged - [1-4094])'
type: object
additionalProperties: false
properties:
state:
description: 'The state of a VLAN tag.'
type: string
enum: [ all, untagged, tagged ]
tag:
description: 'The "tag" is valid if "state" == "tagged".'
type: number
minimum: 1
maximum: 4094
oneOf:
- type: object
required: [ state ]
additionalProperties: false
properties:
state:
type: string
enum: [ all, untagged ]
- type: object
required: [ state, tag ]
additionalProperties: false
properties:
state:
type: string
enum: [ tagged ]
tag:
type: number
which states that when the "state" property has the value "tagged", then both "state" and "tag" are required. However, if "state" is "all" or "untagged", then "tag" is not required.
from json-schema-spec.
@mbroadst , @awwright : Reading back through this I'm pretty sure that:
- The original request is addressed by the
"switch"
proposal, which I'm about to migrate here from the wiki, alongside the"bounding"
proposal which is an alternate approach to the same problem. Although I think"switch"
has more momentum. - The rest of the back and forth was due to a misunderstanding about what "DHCP is false" meant (it literally meant that the value of the
"dhcp"
property wasfalse
, and not that a runtime check of DHCP failed).
If this is true, then there's nothing left to do for this issue. If you agree, could one of you please close it to keep the list of open issue tidy?
from json-schema-spec.
yep! sorry definitely meant to close this sooner.
from json-schema-spec.
This stayed open because I indicated my preference for that. I was going to say let's wait until we get an alternative issue filed, please. I sympathize with reducing the number of open issues, but it's more important to make sure issues that are actually issues are, in fact, being tracked.
Can someone link to such an issue, maybe?
from json-schema-spec.
@awwright My point was that there isn't any issue left to resolve here. What issue are you trying to track?
from json-schema-spec.
@awwright said:
Can someone link to such an issue, maybe?
Issue #64 collects and compares all of the proposals related to "conditionals" in schemas (whether explicit in the form of switch
or by clarifying the intention of the existing oneOf
approaches, which I prefer. It's a kind of enormous issue but I pulled together at least three overlapping proposals so there wasn't really a way to make it short.
from json-schema-spec.
Related Issues (20)
- OneOf property is failing during OAS Schema Validation HOT 4
- Intended interplay between "type" and "enum" HOT 2
- Validation Regex Description (section 7.3.8) should follow format of other string validation types
- Enum : Clarification HOT 2
- Build failure due to Relative JSON Pointer specification HOT 1
- Pattern: clarification on whether leading and trailing delimiters are allowed or required HOT 2
- Omitted `prefixItems` vs empty HOT 1
- Evaluation path: relative to $ref resolved schema or resource/document root? HOT 4
- JSON
- Feature Request: Constraint for single occurrence of a property structure in JSON Schema HOT 1
- Use JSON Pointers instead of 'properties' or 'prefixItems' keywords HOT 16
- Json-schema HOT 1
- How do I get the use Json to get the "about" and "mention" property to work with several subjects? HOT 4
- Statement on annotation values is unclear
- To validate CRUD of table information with a single Json-Schema, we propose an attribute for PrimaryKey. HOT 3
- Futuristic
- owner
- Typo in section 8.2.3 of draft 7 leading to wrong information HOT 4
- String format validation for IP addresses with network mask
- File extension in $id HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from json-schema-spec.