Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why `additionalProperties` is the way to represent Dictionary/Map in Swagger/OpenAPI 2.0

Although I have seen the examples in the OpenAPI spec:

type: object additionalProperties:   $ref: '#/definitions/ComplexModel' 

it isn't obvious to me why the use of additionalProperties is the correct schema for a Map/Dictionary.

It also doesn't help that the only concrete thing that the spec has to say about additionalProperties is:

The following properties are taken from the JSON Schema definition but their definitions were adjusted to the Swagger 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
like image 907
Chen Levy Avatar asked Dec 20 '16 10:12

Chen Levy


People also ask

What is additionalProperties OpenAPI?

OpenAPI lets you define dictionaries where the keys are strings. To define a dictionary, use type: object and use the additionalProperties keyword to specify the type of values in key/value pairs.

What is JSON schema additionalProperties?

The additionalProperties keyword is used to control the handling of extra stuff, that is, properties whose names are not listed in the properties keyword or match any of the regular expressions in the patternProperties keyword. By default any additional properties are allowed.

What are the three primary sections in a swagger specification?

Basic authentication. API key (as a header or query parameter) OAuth 2 common flows (implicit, password, application and access code)


2 Answers

Chen, I think your answer is correct.

Some further background that might be helpful:

In JavaScript, which was the original context for JSON, an object is like a hash map of strings to values, where some values are data, others are functions. You can think of each name-value pair as a property. But JavaScript doesn't have classes, so the property names are not predefined, and each object can have its own independent set of properties.

JSON Schema uses the properties keyword to validate name-value pairs that are known in advance; and uses additionalProperties (or patternProperties, not supported in OpenAPI 2.0) to validate properties that are not known.

For clarity:

  • The property names, or "keys" in the map, must be strings. They cannot be numbers, or any other value.
  • As you said, the property names should be unique. Unfortunately the JSON spec doesn't strictly require uniqueness, but uniqueness is recommended, and expected by most JSON implementations. More background here.
  • properties and additionalProperties can be used alone or in combination. When additionalProperties is used alone, without properties, the object essentially functions as a map<string, T> where T is the type described in the additionalProperties sub-schema. Maybe that helps to answer your original question.
  • When evaluating an object against a single schema, if a property name matches one of those specified in properties, its value only needs to be valid against the sub-schema provided for that property. The additionalProperties sub-schema, if provided, will only be used to validate properties that are not included in the properties map.
  • There are some limitations of additionalProperties as implemented in Swagger's core Java libraries. I've documented these limitations here.
like image 151
Ted Epstein Avatar answered Oct 04 '22 01:10

Ted Epstein


First thing, I found a better explanation for additionalProperties:

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.

So here is how I finally understood this:

Using properties, we can define a known set of properties similar to Python's namedtuple, however if we wish to have something more like Python's dict, or any other hash/map where we can't specify how many keys there are nor what they are in advance, we should use additionalProperties.

additionalProperties will match any property name (that will act as the dict's key, and the $ref or type will be the schema of the dict's value, and since there should not be more than one properties with the same name for every given object, we will get the enforcement of unique keys.

Note that unlike Python's dict that accepts any immutable value as a key, since the keys here are in essence property names, they must be strings. (Thanks Ted Epstein for that clarification). This limitation can be tracked down to pair := string : value in the json specification.

like image 21
Chen Levy Avatar answered Oct 04 '22 00:10

Chen Levy