Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it clear that additionalProperties can only have a schema value #668

Closed
ePaul opened this issue Apr 22, 2016 · 15 comments
Closed

Make it clear that additionalProperties can only have a schema value #668

ePaul opened this issue Apr 22, 2016 · 15 comments

Comments

@ePaul
Copy link
Contributor

ePaul commented Apr 22, 2016

JSON Schema allows for additionalProperties both a boolean or an object value. true is interpreted as "additional properties follow no restrictions", false means "no additional restrictions", and an object is interpreted as a JSON schema applied to the property values (the empty object is thus equivalent to true).

The Schema object description says:

The following properties are taken from the JSON Schema definition but their definitions
were adjusted to the OpenAPI Specification. Their definition is the same as the one from
JSON Schema, only where the original definition references the JSON Schema definition,
the Schema Object definition is used instead.

  • items
  • allOf
  • properties
  • additionalProperties

This would be naively interpreted as additionalProperties can have a boolean or a schema value (with a schema being interpreted as an OpenAPI schema, not a JSON schema).

In Swagger-Codegen #1318, @webron commented that this was actually meant as "the value of additionalProperties can only be a (Swagger) Schema object", not a boolean.

Some more discussion was in #477 here.

(I just hit an API which used booleans in several places, and fails with swagger-codegen.)

To make this clearer in the next version of the spec, I suggest to add the following sentence to the cited paragraph above (before the list):

Alternative values of other types (boolean) are not allowed.

I'm not totally happy with this wording, feel free to propose a better one. Maybe we should instead simply redefine additionalProperties generally?

@dehora
Copy link

dehora commented May 12, 2016

The following properties are taken from the JSON Schema definition but their definitions
were adjusted to the OpenAPI Specification. Their definition is the same as the one from
JSON Schema, only where the original definition references the JSON Schema definition,
the Schema Object definition is used instead.

  • items
  • allOf
  • properties
  • additionalProperties

This is confusing spec language. In particular the last sentence is too hard to follow - the definitions can't be the same and not be the same. Also there don't seem to be any local definitions defined - the link in the statement "the Schema Object definition is used instead." points back to this section.

What seems to be happening here operationally, is that four properties from JSON Schema are being changed in Open API while keeping the property names.

This seems to indicate what's going on, in more direct language

The following property names are taken from JSON Schema specification but their definitions
are changed in Open API to disallow boolean values - only an object value representing a JSON schema applied to the property values is allowed.

  • items
  • allOf
  • properties
  • additionalProperties

@ePaul
Copy link
Contributor Author

ePaul commented May 12, 2016

@dehora I think the point of the original language was to replace all places in a schema where a nested "JSON Schema object" occurs (this is just inside of those four properties, and in some which are not supported at all) with a "Swagger Schema object".

So Swagger model schemas (or now OpenAPI model schemas) work similar to JSON schemas, with some restrictions (e.g. anyOf, oneOf, not, additionalItems, patternProperties are not allowed) and extensions (readOnly, externalDocs, xml, x-* are allowed in addition). Those restrictions and extensions also apply to any nested schema objects in items, allOf, properties and additionalProperties.

Your proposed wording removes this point, because now any JSON schema objects can be nested, even ones which are not legal OpenAPI model schemas. (Also, the value of properties is an objects, only those property values again are schemas. The value of allOf is an array of schemas.)

(I think that boolean values were forbidden is just a side effect, which might have been intended, but was not explicitly written out.)

@ePaul
Copy link
Contributor Author

ePaul commented May 12, 2016

I guess we could instead write the new definitions of those four fields explicitly:

The following properties have similar, but still slightly different definitions as in the JSON schema specification:

Field Name Type Description
items Schema Object For arrays, this defines a schema which has to match all of the elements of the array.
allOf [ Schema Object ] If this is given, all of the given schemas need to match a value for this schema to match the value (in addition to other properties directly in this schema).
properties Properties Object For an object, this defines which properties (and with what kind of values) are allowed in the object.
additionalProperties Schema Object For an object, if this is given, in addition to the properties defined in properties all other property names are allowed. Their values must each match the schema object given here. If this is not given, no other properties than those defined in properties are allowed.

(The definition of items is how I – and I guess everyone I've met – have interpreted it until now ... the definition in JSON schema strangely doesn't say anything about that the array elements actually have to match the schemas.)

In addition, we would need this section about a properties object:

Properties Object

The properties object defines which properties (both names and values) are allowed in an object.

Patterned fields
Field Name Type Description
.* Schema Object This allows a property with the given name. Its values must match the given schema object.

@ralfhandl
Copy link
Contributor

@ePaul The definition of how items is to be interpreted for validating array items is hidden in section 8.2. Array Elements of the JSON Schema specification, quite some distance from the definition of ìtems itself. I knew I had read it somewhere, and still it was hard to find again.

@ePaul
Copy link
Contributor Author

ePaul commented May 13, 2016

@ralfhandl Nicely hidden, thanks for finding. I guess the guiding point here is section 4.4:

4.4. Validation of container instances

Keywords with the possibility to validate container instances (arrays or objects) only validate the instances themselves and not their children (array items or object properties). Some of these keywords do, however, contain information which is necessary for calculating which schema(s) a child must be valid against. The algorithms to calculate a child instance's relevant schema(s) are explained in a separate section.

It should be noted that while an array element will only have to validate against one schema, object member values may have to validate against more than one schema.

Strange way of saying this. I think JSON schema needs some rewording as well, but this is out-of-scope for this discussion.

@webron
Copy link
Member

webron commented May 19, 2016

Thanks @ePaul. We could have definitely done better work with the 2.0 wording, but that's in the past.

I suggest we keep this ticket open but it may be affected by #333.

Parent: #589.

@webron
Copy link
Member

webron commented Jul 21, 2016

Tackling PR: #741

@boillodmanuel
Copy link

Hello,

I wonder how to tell that a definition does not support additional properties. It didn't figure out with a schema?

@handrews
Copy link
Member

Note that in the forthcoming-very-soon-now draft-wright-01 (a.k.a. Draft 06), any schema or subschema, not just "additionalProperties" and "additionalItems", can be a boolean:

true is {}
false is {"not": {}}

This both allows for a more clear expression of intent on behalf of schema authors and allows implementations to optimize these cases- true always passes validation, false always fails, no instance check needed. It also means that the "additional*" keywords are no longer special cases- handling their boolean values is like handling any other boolean values.

The confusing language and section organization about "container instances" has also been reworked btw.

@webron
Copy link
Member

webron commented Feb 22, 2017

3.0 now supports boolean values as well for additionalProperties - introduced by #894.

@rahuljain983
Copy link

how to validate a JSON with known and dynamic property both?
i have a json object which have 2 known (title and description) and 1 unknown property. in that unknown property i want to refer back to my parent object

jmcs pushed a commit to spec-first/connexion that referenced this issue Nov 28, 2018
Currently when object is send as body parameter only properties defined in `properties` in body schema are passed to handler function. Additional keys are filtered out, which is opposite to [spec](https://github.com/OAI/OpenAPI-Specification/blame/3.0.2/versions/3.0.2.md#L2305). For me specification is counter intuitive :(

Changes proposed in this pull request:
 - If `additionalProperties` is not set or is `True`, all properties not defined in `properties` are passed without type casting.
 - If `additionalProperties` declares value type,  unknown properties are cast according to https://github.com/zalando/connexion#type-casting.

The best explanation for `additionalProperties` I found in OAI/OpenAPI-Specification#668 (comment)
@spacether
Copy link

spacether commented Feb 29, 2020

Note that in the forthcoming-very-soon-now draft-wright-01 (a.k.a. Draft 06), any schema or subschema, not just "additionalProperties" and "additionalItems", can be a boolean:

How is additionalProperties True interpreted?
The JSON spec here https://tools.ietf.org/html/draft-fge-json-schema-validation-00#page-13
It sounds like if additionalProperties is True, and any property is given validation succeeds.
Is the below interpretation correct?

additionalProperties: True
-> values must be one of (string, number, boolean, array, object)

additionalProperties: False
no additional properties are allowed

additionalProperties: {}
values must be {str: (string, number, boolean, array, object)}

additionalProperties: string
values must be string

additionalProperties: schema
values must conform to schema

@handrews
Copy link
Member

handrews commented Mar 2, 2020

@spacether TL;DR: additionalProperties: True always passes, because for objects it allows any value for any additional property, and does not require any particular property to exist.

additionalProperties: True and additionalProperties: {} behave identically. True is just a shorthand for the empty schema.

In general, keywords are ignored for instance types that they don't describe, so additionalProperties (and properties, minProperties, maxProperties, and required) is ignored for non-objects.


I don't recommend trying to understand how draft-fge-json-schema-validation-00 explains this, as it's really convoluted. Austin Wright made that document a lot more straightforward in draft-wright-json-schema-validation-01, which is what OpenAPI 3.0 references. However, the boolean schema explanation got left out by accident.

OpenAPI 3.1 will use the latest JSON Schema (probably a draft to be published this month, but at least the current draft which will be referenced by OAS 3.1rc0, and this is now explained in a more straightforward manner in §4.3.2 Boolean Schemas and §9.3.2.3 additionalProperties.

Note that since boolean schemas are no longer special cases for only certain keywords, they don't get mentioned in the individual keyword section. You can always use true in place of {} anywhere you can have a schema.

@MosheElisha
Copy link

Hi,

Can you please clarify how to represent a map of string and simple value (for example, Map<String, String>?

Looking in https://swagger.io/docs/specification/data-models/dictionaries/ it says:

type: object
additionalProperties:
  type: string

Is that correct? If not, how should it be?

Thanks.

@handrews
Copy link
Member

handrews commented Jan 6, 2021

@MosheElisha yes, that is correct. It looks a little weird to have additionalProperties without anything else ("additional to what?" I always want to ask) but it is the correct way to do this. "additional" just means "not otherwise specified," so if there's no other property specification in the same schema object, additionalProperties applies to all properties.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants