Change proposal for "required" attribute

89 views
Skip to first unread message

as1234

unread,
Mar 24, 2011, 11:55:16 AM3/24/11
to JSON Schema
I'm trying to model a quite complex data schema with JSON schema using
exhaustively "$ref" and "extends" I stumbled multiple times across
issues that could get resolved with a different semantic of the
"required" property.

I'm still quite new to JSON schema, to don't hesitate to correct me if
I have a misunderstanding of the spec

My proposal is to define required as

"required" : {
"type" : "array",
"items" : { "type" : "string "}
}

and not to apply it to an individual property of an object, but to the
whole object. The array would then contain the names of all "required"
properties.

Why this?

First of all: "required" primarily puts a restriction on the availalbe
properties of an object (saying that the given property has to exist)
and not that much a restriction on the value of the property (although
technically it also defines that the value is not allowed to be
"undefined"); But e.g. you could still define something like

"requiredAttribute" : {
"required" : true,
"type" : ["null","string"]
}

So you would still have no real value for a required attribute;
"required" just enforces that the attribute is there

Second: When you reuse a (sub)schema the "required" state of the
property is quite often different; Assuming you have two properties of
the same (complex) type, one if required and the other is optional. To
express this in json-schema you have to take care of two things: the
optional one has to be defined "before" the required one (to be able
to make a $ref on it", and then you have to extend the referenced
schema just to be able to set the required attribute:

{
"id" : "#root",
"type" : "object",
"properties" : {
"optional" : {
"id" : "#forReuse",
"type" : "object",
"properties" : {
}
},
"enforced" : {
"extends" : {
"$ref" : "#forReuse"
},
"required" : true
}
}
}

with my proposal you would instead write

{
"id" : "#root",
"type" : "object",
"properties" : {
"enforced" : {
"id" : "#forReuse",
"type" : "object",
"properties" : {
}
},
"optional" : {
"$ref" : "#forReuse"
}
},
"required" : ["enforced"]
}

Why is this better?
- no need to take care of orders (which might be quite difficult in
some situations)
- "required" properties now tied to "#root" instead of the class that
defines the value range of the property
- precise semantic: although the first example doesn't specifc a
"required" value, the spec does, by saying that "required" defaults to
false
- complete semantic: by binding a "required" to objects and not to
schema we don't have to answer what the semantic of a "required"
schema within an array or a union would be


Any comments?

Paul C. Bryan

unread,
Mar 26, 2011, 1:03:22 PM3/26/11
to json-...@googlegroups.com
To sum my understanding of the proposal: make the "requiredness" of object properties an attribute* of the containing object rather than as an attribute of the defined properties themselves.

Some points I'd like to raise with it:

1. Surely when extending an existing schema, one could override a required property to be not required in its new context? So I'm not sure why in your example you say you needed to define the optional one first.  

2. With regard to your point about order, I don't think $ref should necessarily be only for backward references. Many hypertext documents allow forward URI references using fragment identifiers. A popular example is HTML with anchors containing fragment identifiers to anchored links defined later in the document. Should json-schema documents be different, and if so, why?

Paul

*I'm using the word "attribute" here to prevent naming collisions between the metadata and the data.

Kenny Hoxworth

unread,
Mar 26, 2011, 2:28:39 PM3/26/11
to json-...@googlegroups.com
1. Surely when extending an existing schema, one could override a required property to be not required in its new context? So I'm not sure why in your example you say you needed to define the optional one first.  

This is not correct according to the draft 3 definition of 'extends', http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.26. The extending schema does not overwrite attributes or restrictions, it simply adds to them. You can therefore run into situations where a schema can never be valid, such as in your example where the 'requred' attribute it set to 'true' in the extended schema and 'false' in the extending schema.
 
2. With regard to your point about order, I don't think $ref should necessarily be only for backward references. Many hypertext documents allow forward URI references using fragment identifiers. A popular example is HTML with anchors containing fragment identifiers to anchored links defined later in the document. Should json-schema documents be different, and if so, why?

The JSON schema spec does not formally specify whether forward references should be allowed, and thus the behavior is undefined. Because of this, some existing validators allow forward-reference and others do not. 

Paul C. Bryan

unread,
Mar 27, 2011, 6:13:55 PM3/27/11
to json-...@googlegroups.com
On Sat, 2011-03-26 at 14:28 -0400, Kenny Hoxworth wrote:
1. Surely when extending an existing schema, one could override a required property to be not required in its new context? So I'm not sure why in your example you say you needed to define the optional one first.  

This is not correct according to the draft 3 definition of 'extends', http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.26. The extending schema does not overwrite attributes or restrictions, it simply adds to them. You can therefore run into situations where a schema can never be valid, such as in your example where the 'requred' attribute it set to 'true' in the extended schema and 'false' in the extending schema.

Okay, got it.

2. With regard to your point about order, I don't think $ref should necessarily be only for backward references. Many hypertext documents allow forward URI references using fragment identifiers. A popular example is HTML with anchors containing fragment identifiers to anchored links defined later in the document. Should json-schema documents be different, and if so, why?

The JSON schema spec does not formally specify whether forward references should be allowed, and thus the behavior is undefined. Because of this, some existing validators allow forward-reference and others do not. 

I suggest forward references be explicitly allowed to avoid any ambiguity here.

--
You received this message because you are subscribed to the Google Groups "JSON Schema" group.
To post to this group, send email to json-...@googlegroups.com.
To unsubscribe from this group, send email to json-schema...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/json-schema?hl=en.

Kenny Hoxworth

unread,
Mar 27, 2011, 6:26:10 PM3/27/11
to json-...@googlegroups.com
> I suggest forward references be explicitly allowed to avoid any ambiguity here.

I agree completely; i support the issue of forward-referencing being
explicitly defined in the next draft.

Kris Zyp

unread,
Mar 28, 2011, 12:53:38 PM3/28/11
to json-...@googlegroups.com, Paul C. Bryan


On Saturday, March 26, 2011 11:03:22 AM UTC-6, Paul C. Bryan wrote:
To sum my understanding of the proposal: make the "requiredness" of object properties an attribute* of the containing object rather than as an attribute of the defined properties themselves.

Some points I'd like to raise with it:

1. Surely when extending an existing schema, one could override a required property to be not required in its new context? So I'm not sure why in your example you say you needed to define the optional one first.  

2. With regard to your point about order, I don't think $ref should necessarily be only for backward references. Many hypertext documents allow forward URI references using fragment identifiers. A popular example is HTML with anchors containing fragment identifiers to anchored links defined later in the document. Should json-schema documents be different, and if so, why?

I had assumed everyone would assume forward references (in document) are legal (just as legal as backwards reference) since there is no wording indicating only backwards references are allowed. We should make support for forward references more explicit in the spec.
Thanks,
Kris

Gary Court

unread,
Mar 30, 2011, 3:04:38 PM3/30/11
to json-...@googlegroups.com
This is actually a really good suggestion. For the same reasons that
the "requires" attribute was changed to "dependencies" (and moved into
the parent object), it would make sense to move "required" to object
type definitions, and define it's children. However, I would highly
recommend changing the name of this attribute to prevent confusion
with the older spec.

A better suggestion may be to deprecate "requires" and allow
"dependencies" to accept boolean values; where if a property in
"dependencies" is true, then that property of the instance object must
exist. Example:

{
"type" : "object",
"properties" : {
"a" : { "type" : "string" },
"b" : { "type" : "number" }
},
"dependencies" : {
"a" : true
}
}

-Gary

Reply all
Reply to author
Forward
0 new messages