@andersbohn thanks for the investigation, indeed this seems to be the same issue as the one you linked (1203). It’s due to the fact that we currently assume that there’s a single schema for each type - which, with customisations, might not be the case.
However, with OpenAPI 3.1 now fully supported by Swagger (the dominant “consumer” of the specs generated by tapir), maybe we can fix this.
To make sure we’re on the same page, here’s my simplified example. First, the data classes and the endpoint:
case class Data1(x: String)
case class Data2(@deprecated @description("aaa") a: Data1, @description("bbb") b: Data1)
val e = infallibleEndpoint.get.in(jsonBody[Data2])
When interpreted to yaml, we get (somewhat simplified):
openapi: 3.1.0
info:
title: Fruits
version: '1.0'
paths:
/:
get:
operationId: getRoot
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Data2'
required: true
responses:
'200':
description: ''
components:
schemas:
Data1:
required:
- x
type: object
properties:
x:
type: string
description: aaa
deprecated: true
Data2:
required:
- a
- b
type: object
properties:
a:
$ref: '#/components/schemas/Data1'
b:
$ref: '#/components/schemas/Data1'
So the schema for Data1 now has the properties of the first customisation, while the second is lost. Instead, we’d want to add these customisations to the ref-s:
openapi: 3.1.0
info:
title: Fruits
version: '1.0'
paths:
/:
get:
operationId: getRoot
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Data2'
required: true
responses:
'200':
description: ''
components:
schemas:
Data1:
required:
- x
type: object
properties:
x:
type: string
Data2:
required:
- a
- b
type: object
properties:
a:
$ref: '#/components/schemas/Data1'
description: aaa
deprecated: true
b:
$ref: '#/components/schemas/Data1'
description: bbb
This renders properly in Swagger UI and redoc according to my tests. There’s also a number of other cases (respons bodies, top-level references etc.) that we’d have to check.
But I think my stratego to implement this would be to see if there are competing schemas for the same type, keep only the common fields, and any extras would get moved to $ref. Hopefully this won’t produce some unwanted results 