swagger-core icon indicating copy to clipboard operation
swagger-core copied to clipboard

Document Hashmap with @Schema

Open matus-m opened this issue 6 years ago • 6 comments

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

matus-m avatar Jan 23 '19 09:01 matus-m

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;
}

frantuma avatar Feb 04 '19 10:02 frantuma

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

clounie avatar Apr 16 '19 16:04 clounie

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

ndtreviv avatar Sep 03 '20 12:09 ndtreviv

Hi! @frantuma How's the progress with this one?

mchmielarz avatar Nov 03 '21 14:11 mchmielarz

Hello @frantuma, is there any update on this? It seems bizarre that describing an API response using a map isn't natively supported the same way that Schema or ArraySchema are. The current solutions that you've shown above lead to bad practices

haarisdev avatar Apr 06 '22 13:04 haarisdev

Any update on this? @frantuma I encountered this problem this week when I implemented an API that returns a HashMap.

MansSandberg avatar Sep 19 '22 05:09 MansSandberg

I also faced this limitation today, Does anyone know the status on this?

atulkumarr123 avatar Jun 05 '23 07:06 atulkumarr123

Hey @frantuma , any update on this one? Thanks!

Plonk42 avatar Jun 25 '23 23:06 Plonk42

Also looking for an update on this @frantuma

amccourt avatar Jul 12 '23 20:07 amccourt

#4475 adds support for additionalPropertiesArraySchema in @Content annotation which should cover all use cases mentioned in this ticket related to additionalProperties. This test and related resource class demonstrates usage in various scenarios.

Closing ticket, will monitor for any comment/feedback

frantuma avatar Sep 17 '23 19:09 frantuma