Swagger-core: Document Hashmap with @Schema

Created on 23 Jan 2019  路  3Comments  路  Source: swagger-api/swagger-core

hi,

how would one describe an api response, that returns Map<String, List<ComplexObject>> using the v2 annotations? Or Map<String, ComplexObject>?

According to OA3 schema it is possible to model like this, using additionalProperties:

openapi: "3.0.0"
info:
  title: Swagger Petstore
servers:
  - url: http://petstore.swagger.io/v1
paths:
  /petGroups:
    get:
      operationId: listPetGroups
      tags:
        - pets
      responses:
        '200':
          description: Pets grouped by Ownername
          content:
            application/json:    
              schema:
                $ref: "#/components/schemas/MapResponse"


components:
  schemas:
    MapResponse:        # <---- dictionary<String,Array<Pet>>
      type: object
      additionalProperties:
        $ref: '#/components/schemas/Pets'
    Pet:
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
    Pets:
      type: array
      items:
        $ref: "#/components/schemas/Pet"

But I do not see a way, how to describe this structure on the server side using java annotations, as @Schema does not have additionalProperties.

(end goal is to generate schema from server code, or at least to validate, that the server code matches the schema above)
Thanks

Most helpful comment

Something like this would be great:

content = @Content(map = @MapSchema(key = @Schema(implementation = String.class), value = @Schema(implementation = XXX.class)))

And so would produce the following in swagger ui:

{
  "key": XXX > { ... }
}

All 3 comments

one way to achieve what you want is having your resource method return e.g. Map<String, List<Pet>> which would result in a spec with a response to the one above:

        @GET
        @Path("/path")
        public Map<String, List<Pet>> simpleGet(String data) {
            return null;
        }

a more "invasive" alternative would be defining a class extending e.g. HashMap<String, Pet> to be used in implementation field of @Content annotation within @Response:

class MyModel extends HashMap<String, Pet> {}
@Operation(responses = {
  @ApiResponse(
    responseCode = "200",
    content = @Content(
      mediaType = "application/json", 
      schema = @Schema(implementation = MyModel.class)))
  }
)
@GET
@Path("/path")
public Whatever simpleGet(String data) {
      return null;
}

It seems like something that should be automatically introspected and applied, especially for Map<String, XXX> - no need for extra syntax.

Something like this would be great:

content = @Content(map = @MapSchema(key = @Schema(implementation = String.class), value = @Schema(implementation = XXX.class)))

And so would produce the following in swagger ui:

{
  "key": XXX > { ... }
}
Was this page helpful?
0 / 5 - 0 ratings