'OpenApi generator doesn't allow multiple schema in content

I've an OpenAPI contract like this:

openapi: 3.0.1
info:
  title: Internal API
  version: ''
tags:
  - name: Calendar
    description: Api for Calendar resource
paths:
  '/api/v1/appointments/{id}':
    get:
      tags:
        - Calendar
      summary: Get the given appointment
      description: Get the given appointment
      operationId: findById
      parameters:
        - name: id
          in: path
          description: The appointment Id
          required: true
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: Successful operation
          content:
            application/vnd.widget+json:
              schema:
                $ref: '#/components/schemas/AppointmentWidgetDto'
            application/json:
              schema:
                $ref: '#/components/schemas/Appointment'
      
components:
  schemas:
    AppointmentWidgetDto:
      required:
        - contactEmail
        - contactName
        - contactPhone
        - endDate
        - startDate
        - store
        - title
      type: object
      properties:
        store:
          $ref: '#/components/schemas/Store'
        title:
          maxLength: 255
          minLength: 0
          type: string
        description:
          maxLength: 1024
          minLength: 0
          type: string
        type:
          maxLength: 50
          minLength: 0
          type: string
        icon:
          maxLength: 50
          minLength: 0
          type: string
        startDate:
          type: string
          format: date-time
        endDate:
          type: string
          format: date-time
        contact:
          $ref: '#/components/schemas/Contact'
        contactName:
          type: string
        contactEmail:
          type: string
        contactPhone:
          type: string
    AuditUser:
      type: object
      properties:
        sid:
          type: string
        fullName:
          type: string
    Contact:
      required:
        - billingCountry
        - personType
        - preset
        - publicAdministration
        - shippingCountry
        - status
        - type
      type: object
      properties:
        id:
          type: integer
          format: int64
        sid:
          type: string
        createdBy:
          $ref: '#/components/schemas/AuditUser'
        createdDate:
          type: string
          format: date-time
        lastModifiedDate:
          type: string
          format: date-time
        lastModifiedBy:
          $ref: '#/components/schemas/AuditUser'
        version:
          type: integer
          format: int64
        userInputTime:
          type: integer
          format: int64
        type:
          type: string
          enum:
            - CUSTOMER
            - SUPPLIER
            - CUSTOMER_SUPPLIER
            - SUBCONTRACTOR
        personType:
          type: string
          enum:
            - NATURAL_PERSON
            - LEGAL_PERSON
        extCode:
          maxLength: 50
          minLength: 0
          type: string
        lotteryCode:
          maxLength: 8
          minLength: 0
          type: string
        firstName:
          type: string
        lastName:
          type: string
        companyName:
          type: string
        fullName:
          type: string
          readOnly: true
        gender:
          type: string
          enum:
            - MALE
            - FEMALE
            - OTHER
        birthDate:
          type: string
          format: date
        birthCity:
          type: string
        job:
          maxLength: 100
          minLength: 0
          type: string
        billingAddress:
          type: string
        billingZipCode:
          type: string
        billingCity:
          type: string
        billingDistrict:
          type: string
        billingCountry:
          maxLength: 2
          minLength: 2
          type: string
        shippingAddress:
          type: string
        shippingZipCode:
          type: string
        shippingCity:
          type: string
        shippingDistrict:
          type: string
        shippingCountry:
          maxLength: 2
          minLength: 2
          type: string
        taxCode:
          type: string
        vatNumber:
          type: string
        landlinePhone:
          type: string
        mobilePhone:
          type: string
        fax:
          type: string
        email:
          type: string
        certifiedEmail:
          type: string
        workingDistance:
          type: string
          enum:
            - FAR_NEAR
            - INTERMEDIATE_NEAR
            - NEAR
            - FAR_INTERMEDIATE
        bankName:
          type: string
        iban:
          type: string
        swift:
          type: string
        publicAdministration:
          type: boolean
        sdiAccountId:
          type: string
        store:
          $ref: '#/components/schemas/Store'
        preset:
          type: boolean
        avatar:
          type: boolean
        status:
          type: string
          enum:
            - ACTIVE
            - DECEASED
        completenessScore:
          type: number
          readOnly: true
        tags:
          type: string
        age:
          type: integer
          format: int32
    Store:
      required:
        - address
        - city
        - code
        - country
        - district
        - name
        - whatsAppEnabled
        - zipCode
      type: object
      properties:
        id:
          type: integer
          format: int64
        sid:
          type: string
        createdBy:
          $ref: '#/components/schemas/AuditUser'
        createdDate:
          type: string
          format: date-time
        lastModifiedDate:
          type: string
          format: date-time
        lastModifiedBy:
          $ref: '#/components/schemas/AuditUser'
        version:
          type: integer
          format: int64
        userInputTime:
          type: integer
          format: int64
        name:
          type: string
        code:
          type: string
        extCode:
          maxLength: 50
          minLength: 0
          type: string
        address:
          type: string
        zipCode:
          type: string
        city:
          type: string
        district:
          type: string
        country:
          maxLength: 2
          minLength: 2
          type: string
        landlinePhone:
          type: string
        mobilePhone:
          type: string
        whatsAppEnabled:
          type: boolean
        fax:
          type: string
        email:
          type: string
        certifiedEmail:
          type: string
        openingHours:
          maxLength: 1024
          minLength: 0
          type: string
        contactMinScore:
          maximum: 10
          minimum: 0
          type: number
    Agent:
      required:
        - country
        - email
        - firstName
        - gender
        - language
        - lastName
        - user
        - verified
      type: object
      properties:
        id:
          type: integer
          format: int64
        sid:
          type: string
        createdBy:
          $ref: '#/components/schemas/AuditUser'
        createdDate:
          type: string
          format: date-time
        lastModifiedDate:
          type: string
          format: date-time
        lastModifiedBy:
          $ref: '#/components/schemas/AuditUser'
        version:
          type: integer
          format: int64
        userInputTime:
          type: integer
          format: int64
        user:
          $ref: '#/components/schemas/User'
        firstName:
          type: string
        lastName:
          type: string
        gender:
          type: string
          enum:
            - MALE
            - FEMALE
            - OTHER
        color:
          maxLength: 30
          minLength: 0
          type: string
        employeeId:
          type: string
        address:
          type: string
        zipCode:
          type: string
        city:
          type: string
        district:
          type: string
        country:
          maxLength: 2
          minLength: 2
          type: string
        birthDate:
          type: string
          format: date
        taxCode:
          type: string
        vatNumber:
          type: string
        landlinePhone:
          type: string
        mobilePhone:
          type: string
        email:
          type: string
        verified:
          type: boolean
          readOnly: true
        language:
          maxLength: 2
          minLength: 2
          type: string
        iban:
          type: string
        swift:
          type: string
        stores:
          uniqueItems: true
          type: array
          items:
            $ref: '#/components/schemas/Store'
        avatar:
          type: boolean
          readOnly: true
        tourCompleted:
          type: boolean
          readOnly: true
        enabled:
          type: boolean
          writeOnly: true
        password:
          type: string
          writeOnly: true
        lastPasswordUpdate:
          type: string
          format: date-time
        username:
          type: string
        roles:
          uniqueItems: true
          type: array
          items:
            type: string
            enum:
              - ROLE_ADMIN
        userSid:
          type: string
    Appointment:
      required:
        - allDay
        - endDate
        - startDate
        - status
        - store
        - title
      type: object
      properties:
        id:
          type: integer
          format: int64
        sid:
          type: string
        createdBy:
          $ref: '#/components/schemas/AuditUser'
        createdDate:
          type: string
          format: date-time
        lastModifiedDate:
          type: string
          format: date-time
        lastModifiedBy:
          $ref: '#/components/schemas/AuditUser'
        version:
          type: integer
          format: int64
        userInputTime:
          type: integer
          format: int64
        store:
          $ref: '#/components/schemas/Store'
        title:
          maxLength: 255
          minLength: 0
          type: string
        description:
          maxLength: 1024
          minLength: 0
          type: string
        color:
          maxLength: 30
          minLength: 0
          type: string
        type:
          maxLength: 50
          minLength: 0
          type: string
        icon:
          maxLength: 50
          minLength: 0
          type: string
        location:
          maxLength: 255
          minLength: 0
          type: string
        startDate:
          type: string
          format: date-time
        endDate:
          type: string
          format: date-time
        allDay:
          type: boolean
        contact:
          $ref: '#/components/schemas/Contact'
        contactName:
          type: string
        contactEmail:
          type: string
        contactPhone:
          type: string
        agent:
          $ref: '#/components/schemas/Agent'
        agentName:
          type: string
        status:
          type: string
          readOnly: true
          enum:
            - TO_APPROVE
            - VALID
            - CANCELED
            - DECLINED
    GrantedAuthority:
      type: object
      properties:
        authority:
          type: string
    User:
      required:
        - enabled
        - fullName
        - roles
        - username
      type: object
      properties:
        id:
          type: integer
          format: int64
        sid:
          type: string
        createdBy:
          $ref: '#/components/schemas/AuditUser'
        createdDate:
          type: string
          format: date-time
        lastModifiedDate:
          type: string
          format: date-time
        lastModifiedBy:
          $ref: '#/components/schemas/AuditUser'
        version:
          type: integer
          format: int64
        userInputTime:
          type: integer
          format: int64
        fullName:
          type: string
        username:
          maxLength: 255
          minLength: 3
          type: string
        enabled:
          type: boolean
          readOnly: true
        roles:
          maxItems: 2147483647
          minItems: 1
          uniqueItems: true
          type: array
          items:
            type: string
            enum:
              - ROLE_ADMIN
        accountNonExpired:
          type: boolean
        credentialsNonExpired:
          type: boolean
        authorities:
          type: array
          items:
            $ref: '#/components/schemas/GrantedAuthority'
        accountNonLocked:
          type: boolean

I want my endpoint /api/v1/appointments/{id} return 2 different representations of my resource Appointment: the full resource and a light one (with less data). I thought using content's schema is the right thing to do, so the client can easily decide what it wants.

I tried to generate some clients from this contract using Swagger editor and OpenApi generator but I see these Warning:

[WARNING] Multiple schemas found in the OAS 'content' section, returning only the first one (application/vnd.widget+json)

and my client, as expected from that message, has only one method that returns only 1 representation of the resource.

I found this bug https://github.com/OpenAPITools/openapi-generator/issues/144, but at the same time I think this is a very basic concept of HTTP/REST and I'm bit surpriced it doesn't work. Indeed I'm questioning myself doing something wrong. Is there a way to describe a single endpoint returning different representations of the same resouce (OpenApi contract) generating the client with both methods needed to get the already mentioned resource's representations?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source