Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to supply inner type for the array parameter in Swagger?

I have the following YAML for Swagger:

swagger: '2.0'
info:
  ...
host: adam.noncd.db.de
basePath: /api/v1.0
schemes:
  - https
consumes:
  - application/json
produces:
  - application/json
paths:

  /facilities:
    get:
      description: Access to the facilities known to the system
      operationId: findFacilities
      produces:
        - application/json
      parameters:
        - name: type
          in: query
          description: type of the facility to filter by
          default: ["ESCALATOR", "ELEVATOR"]
          required: false
          type: array
          items:
            enum: ["ESCALATOR", "ELEVATOR"]
          collectionFormat: csv
          uniqueItems: true
        - name: state
          in: query
          description: the state of the facility to filter by
          default: ["ACTIVE", "INACTIVE", "UNKNOWN"]
          required: false
          type: array
          items:
            enum: ["ACTIVE", "INACTIVE", "UNKNOWN"]
          collectionFormat: csv
          uniqueItems: true

      responses:
        '200':
          description: facility data
          schema:
            type: array
            items:
              $ref: '#/definitions/facility'
        '400':
          description: The given filters contained invalid values.
        '406':
          description: The requested representation format is not available.
        '500':
          description: A processing error has occurred.
        '503':
          description: The service has been disabled temporarily.


  '/facilities/{equipmentnumber}':
    get:
      description: Returns the facility identify by equipmentnumber
      operationId: getFacilityByEquipmentNumber
      produces:
        - application/json
      parameters:
        - name: equipmentnumber
          in: path
          description: equipmentnumber of the facility to fetch
          required: true
          type: integer
          format: int64
          minimum: 1
      responses:
        '200':
          description: Facility data
          schema:
            $ref: '#/definitions/facility'
        '404':
          description: The requested facility could not be found.
        '406':
          description: The requested representation format is not available.
        '500':
          description: A processing error has occurred.
        '503':
          description: The service has been disabled temporarily.

  '/stations/{stationnumber}':
    get:
      description: Returns the railway station identified by stationnumber
      operationId: findStationByStationNumber
      produces:
        - application/json
      parameters:
        - name: stationnumber
          in: path
          description: stationnumber of the station to fetch
          required: true
          type: integer
          format: int64
          minimum: 1
      responses:
        '200':
          description: station data
          schema:
            $ref: '#/definitions/station'
        '406':
          description: Requested representation format is not available.
        '500':
          description: A processing error has occurred.
        '503':
          description: The service has been disabled temporarily.            

definitions:

  station:
     type: object
     required:
       - stationnumber
       - name
     properties:
      stationnumber:
        type: integer
        format: int64
        description: "Identification number of the station"
      name:
        type: string
        description: "Name of the station"
      facilities:
        type: array
        items:
          $ref: '#/definitions/facility'

  facility:
    type: object
    required:
      - equipmentnumber
      - type
      - state
      - stationnumber
    properties:
      equipmentnumber:
        type: integer
        format: int64
      'type':
        type: string
        enum: ["ESCALATOR", "ELEVATOR"]
      'description':
        type: string
        description: Textual description of place
      geocoordX:
        type: number
        format: double
        description: geocoordinate component in DB REF format
      geocoordY:
        type: number
        format: double
        description: geocoordinate component in DB REF format
      state:
        type: string
        enum: ["ACTIVE", "INACTIVE", "UNKNOWN"]
      stationnumber:
        type: integer
        format: int64

When generating a Java client with Swagger Codegen I'm getting the following warnings:

[WARNING] no property from null, null, {ENUM=[ESCALATOR, ELEVATOR], TITLE=null, DESCRIPTION=null, DEFAULT=null, PATTERN=null, DESCRIMINATOR=null, MIN_ITEMS=null, MAX_ITEMS=null, MIN_PROPERTIES=null, MAX_PROPERTIES=null, MIN_LENGTH=null, MAX_LENGTH=null, MINIMUM=null, MAXIMUM=null, EXCLUSIVE_MINIMUM=null, EXCLUSIVE_MAXIMUM=null, UNIQUE_ITEMS=null, EXAMPLE=null, TYPE=null, FORMAT=null, READ_ONLY=null, VENDOR_EXTENSIONS={}}
[WARNING] no property from null, null, {ENUM=[ACTIVE, INACTIVE, UNKNOWN], TITLE=null, DESCRIPTION=null, DEFAULT=null, PATTERN=null, DESCRIMINATOR=null, MIN_ITEMS=null, MAX_ITEMS=null, MIN_PROPERTIES=null, MAX_PROPERTIES=null, MIN_LENGTH=null, MAX_LENGTH=null, MINIMUM=null, MAXIMUM=null, EXCLUSIVE_MINIMUM=null, EXCLUSIVE_MAXIMUM=null, UNIQUE_ITEMS=null, EXAMPLE=null, TYPE=null, FORMAT=null, READ_ONLY=null, VENDOR_EXTENSIONS={}}
...
[WARNING] warning!  No inner type supplied for array parameter "type", using String
[WARNING] warning!  No inner type supplied for array parameter "state", using String

As you can see, Swagger uses strings for type and state. In the generated API I'm getting the following method signature:

public List<Facility> findFacilities (List<String> type, List<String> state) 
throws ApiException;

So Swagger is using strings instead of the generated enums Facility.TypeEnum and Facility.StateEnum. Apparently this has something to do with the warnings. So if I'd manage to "supply inner type for the array parameter" I think I'll also get enums in the signature. But I could not find a configure it in YAML.

How can I fix my YAML definition to make Swagger use enums instead of strings?
How do I supply inner type for the array parameter?

like image 931
lexicore Avatar asked Jan 06 '23 22:01

lexicore


2 Answers

You need to provide valid JSON schema to define the inner type for the array. For example:

yaml items: enum: ["ACTIVE", "INACTIVE", "UNKNOWN"]

dos not specify the type of the inner value, just the allowable values. The correct definition would be:

items:
  type: string
  enum: ['ACTIVE', 'INACTIVE', 'UNKNOWN']

While this seems repetitive (meaning, one can assume from the type of the allowable values in the enum that it is a string), JSON schema wants you to be explicit about the type.

like image 198
fehguy Avatar answered Jan 22 '23 07:01

fehguy


Adding the type attribute as suggested by @fehguy will fix the warnings during codegeneration, but the generated Java code will still use List<String> for the state/type parameters. This is because the inline enums you specify as the parameter list won't be generated, it needs to be defined in the definitions section.

Note that even if the enum code had been generated for the inlined parameter specification it wouldn't be the enum you want. Each enum you specify inlined in swagger will get it's own separate Java enum implementation, even if they have the same values. So e.g. the state parameter enum type would have no connection with the state enum type defined in the facility object.

The solution is to define the enums separately in the definitions section and then reference these definitions with $ref instead of having inline definitions.

NOTE: there is a bug/missing feature in the current swagger-codegen release (2.1.4) - Java enums are not generated from swagger enum specifications. You need to build swagger-codegen from the latest github branch to get it to work for now.

Here's the modified specification using explicit enum specifications (states_enum and types_enum) and $ref's

swagger: '2.0'
info: foo
host: adam.noncd.db.de
basePath: /api/v1.0
schemes:
  - https
consumes:
  - application/json
produces:
  - application/json
paths:

  /facilities:
    get:
      description: Access to the facilities known to the system
      operationId: findFacilities
      produces:
        - application/json
      parameters:
        - name: type
          in: query
          description: type of the facility to filter by
          default: ["ESCALATOR", "ELEVATOR"]
          required: false
          type: array
          items:
            $ref: "#/definitions/types_enum"
          collectionFormat: csv
          uniqueItems: true
        - name: state
          in: query
          description: the state of the facility to filter by
          default: ["ACTIVE", "INACTIVE", "UNKNOWN"]
          required: false
          type: array
          items:
            $ref: "#/definitions/states_enum"
          collectionFormat: csv
          uniqueItems: true

      responses:
        '200':
          description: facility data
          schema:
            type: array
            items:
              $ref: '#/definitions/facility'
        '400':
          description: The given filters contained invalid values.
        '406':
          description: The requested representation format is not available.
        '500':
          description: A processing error has occurred.
        '503':
          description: The service has been disabled temporarily.


  '/facilities/{equipmentnumber}':
    get:
      description: Returns the facility identify by equipmentnumber
      operationId: getFacilityByEquipmentNumber
      produces:
        - application/json
      parameters:
        - name: equipmentnumber
          in: path
          description: equipmentnumber of the facility to fetch
          required: true
          type: integer
          format: int64
          minimum: 1
      responses:
        '200':
          description: Facility data
          schema:
            $ref: '#/definitions/facility'
        '404':
          description: The requested facility could not be found.
        '406':
          description: The requested representation format is not available.
        '500':
          description: A processing error has occurred.
        '503':
          description: The service has been disabled temporarily.

  '/stations/{stationnumber}':
    get:
      description: Returns the railway station identified by stationnumber
      operationId: findStationByStationNumber
      produces:
        - application/json
      parameters:
        - name: stationnumber
          in: path
          description: stationnumber of the station to fetch
          required: true
          type: integer
          format: int64
          minimum: 1
      responses:
        '200':
          description: station data
          schema:
            $ref: '#/definitions/station'
        '406':
          description: Requested representation format is not available.
        '500':
          description: A processing error has occurred.
        '503':
          description: The service has been disabled temporarily.            

definitions:

  states_enum:
    type: string
    enum: ["ACTIVE", "INACTIVE", "UNKNOWN"]

  types_enum:
    type: string
    enum: ["ESCALATOR", "ELEVATOR"]

  station:
     type: object
     required:
       - stationnumber
       - name
     properties:
      stationnumber:
        type: integer
        format: int64
        description: "Identification number of the station"
      name:
        type: string
        description: "Name of the station"
      facilities:
        type: array
        items:
          $ref: '#/definitions/facility'

  facility:
    type: object
    required:
      - equipmentnumber
      - type
      - state
      - stationnumber
    properties:
      equipmentnumber:
        type: integer
        format: int64
      'type':
        $ref: "#/definitions/types_enum"
      'description':
        type: string
        description: Textual description of place
      geocoordX:
        type: number
        format: double
        description: geocoordinate component in DB REF format
      geocoordY:
        type: number
        format: double
        description: geocoordinate component in DB REF format
      state:
        $ref: "#/definitions/states_enum"
      stationnumber:
        type: integer
        format: int64
like image 34
johlo Avatar answered Jan 22 '23 06:01

johlo