Openapi-specification: Make it clear that `additionalProperties` can only have a schema value

Created on 22 Apr 2016  Â·  15Comments  Â·  Source: OAI/OpenAPI-Specification

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?

Documentation Sub Issue

Most helpful comment

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. |

All 15 comments

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

@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.)_

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. |

@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.

@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.

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.

Tackling PR: #741

Hello,

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

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.

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

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

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

@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.

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.

@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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

satkunas picture satkunas  Â·  4Comments

rossi-jeff picture rossi-jeff  Â·  5Comments

jblazek picture jblazek  Â·  3Comments

kolisko picture kolisko  Â·  4Comments

ePaul picture ePaul  Â·  5Comments