'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 |
---|