Docs / Schemas

Maps

How a map describes an object whose keys are not known in advance, and how it compares with an object.

An object whose keys are not known in advance, but whose values all have the same shape, is a map. values is the node of every value, and the key is always a string:

yaml
PetsByName:
  type: map
  values:
    ref: Pet

describes

json
{ "bob": { "name": "Bob" }, "sky": { "name": "Sky" } }

A map without values is rejected:

publish error
contract validation failed
  - petstore_api.yaml: map schema without values at schemas PetsByName

A contract written before map existed declares a map as type: object with values. It is rejected with two lines at the same property, one for values and one for the missing properties, and the fix is to write type: map in place of type: object:

publish error
contract validation failed
  - petstore_web.yaml: "values" is not allowed on an object schema at schemas Owner properties pets, use it with "type: map"
  - petstore_web.yaml: object schema without properties at schemas Owner properties pets, declare the keys you read, or use "type: map" with "values" if the keys vary

values does not accept optional. When the map may be missing, the property that holds it is optional; when a value may be null, values is nullable: true:

publish error
contract validation failed
  - petstore_api.yaml: "optional" is not allowed on map values at schemas Pet properties scores values, mark the property that holds the map optional, or use "nullable: true" for a value that may be null

A map only matches a map. Two maps compare their values like the items of an array: type, nullable and their own members. In a break line the dynamic key is written {}, as in $.pets{}.name, and a map's type is written map<T>, as an array's is array<T>.

A map on one side and an object on the other is a type mismatch on the property itself, and nothing inside it is compared. Here petstore_api sends pets as an object with the properties bob and sky, and petstore_web reads it as a map:

can-i-deploy output
petstore_api 1.5.0 cannot be deployed to production

petstore_web (1.4.0, deployed):
  Owner.pets β€” petstore_api provides it as object, but petstore_web reads map<object>
    β†’ petstore_api: provide it as map<object>
    β†’ petstore_web: read it as object there
      Β· GET /owners/* response 200 at "$.pets" (petstore_web: Owner.pets)

The fix is to describe the same shape on both sides. When the keys are fixed, both sides declare them as properties of an object, and leave out a key with a reserved character in its name. When the keys vary, both sides declare a map.