Swagger: map of <string, Object>

Solution 1:

Using additionalPropertiesis the proper way to describe hashmap with OpenAPI (fka. Swagger) Specification but Swagger UI do not render them for now.

The issue is tracked here https://github.com/swagger-api/swagger-ui/issues/1248

Meanwhile you can use this trick: define a non required property (defaultin the example below) of the same type of the map's objects and give some hint within the description:

swagger: "2.0"
info:
  version: 1.0.0
  title: Hashmap
  
paths: {}

definitions:
  MapItem:
    properties:
      firstname:
        type: string
      lastname:
        type: string
  Map:
    description: a (key, MapItem) map. `default`is an example key
    properties:
      default:
        $ref: '#/definitions/MapItem'
    additionalProperties:
      $ref: '#/definitions/MapItem'

This description does not modify API contract and improves documentation.

Solution 2:

If I understand it correctly, the basic problem is that there is no universally accepted JSON mapping for a Java Map, especially when the key is more complex than a string. I have seen that GSON takes one approach (treat the key as an object), whereas Jackson takes another (serialise the key to a string). The c# equivalent to a Map (a Dictionary) uses a third approach (treating each entry as a key-value object in its own right with properties called "Key" and "Value"). As Swagger tries to be agnostic to language and serialiser, this puts it in an impossible position.

Solution 3:

you can simply use type as object. When we are parsing data from frontend we have no such thing Map<Key,value>. we are just sending objects. Map is up to backend stuf. that is why I am asking to use object as the type. In objects we can send key value pairs. as the example given below

  metaData:
    type: object
    example: {
      "heading":"comfirmation email"
    }

Solution 4:

By using additionalProperties:

definitions:
  String-StringStringMap: # <-- use this as your result
    type: object
    additionalProperties:
      $ref: "#/definitions/StringStringMap"

  StringStringMap:
      type: object
      additionalProperties:
        type: string

this results a 2 level map:

{
  "additionalProp1": {
    "additionalProp1": "string",
    "additionalProp2": "string",
    "additionalProp3": "string"
  },
  "additionalProp2": {
    "additionalProp1": "string",
    "additionalProp2": "string",
    "additionalProp3": "string"
  },
  "additionalProp3": {
    "additionalProp1": "string",
    "additionalProp2": "string",
    "additionalProp3": "string"
  }
}

With same idea you can specify a 3 level map also.