'How to programmatically include a custom property into spec generated by springdoc-openapi?
I have an endpoint that accepts and sends back objects of the form {a: 1, b: 2, c:3} where either b or c is missing. To precise, admissible objects are {a: 1, b: 2}, {a: 1, c:3} where the values are free to choose.
@RestController
@RequestMapping("/v42")
public class MyAPI {
@PostMapping("/subsets")
public Subset getSubsets(@RequestParam Subset subset) {
return subset;
}
}
Internally the JSON object is parsed into a subclass of Subset:
@JsonDeserialize(using = SubsetDeserializer.class)
public abstract class Subset {
}
@AllArgsConstructor
public class SubsetAB extends Subset {
int a,b;
}
@AllArgsConstructor
public class SubsetAC extends Subset {
int a,c;
}
But since the parent class has no fields the generated spec does not list them:
paths:
/v42/subsets:
post:
tags:
- pet-api
operationId: getSubset
parameters:
- name: subset
in: query
required: true
schema:
$ref: '#/components/schemas/com.myservice.api.v42.Subset'
responses:
200:
description: OK
content:
'*/*':
schema:
$ref: '#/components/schemas/com.myservice.api.v42.Subset'
...
components:
schemas:
com.myservice.api.v42.Subset:
type: object
How can I annotate my Subset class so that if shows as having either the form SubsetAB or SubsetAC?
I've tried:
Defining my own examples:
@PostMapping("/subsets")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Subset that comes back", content = {
@Content(mediaType = "application/json", examples = {
@ExampleObject(name = "subsetAB", description = "With A and B", value = "{\"a\": 1, \"b\": 2}"),
@ExampleObject(name = "subsetAC", description = "With A and C", value = "{\"a\": 1, \"c\": 3}")
})
})
})
public Subset getSubset(@io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(examples = {
@ExampleObject(name = "subsetAB", description = "With A and B", value = "{\"a\": 1, \"b\": 2}"),
@ExampleObject(name = "subsetAC", description = "With A and C", value = "{\"a\": 1, \"c\": 3}")
})) @RequestBody Subset subset) {
return subset;
}
This works pretty good already:
paths:
/v42/subsets:
post:
tags:
- pet-api
operationId: getSubset
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/com.myservice.api.v42.Subset'
examples:
subsetAB:
description: With A and B
value:
a: 1
b: 2
subsetAC:
description: With A and C
value:
a: 1
c: 3
required: true
responses:
200:
description: Subset that comes back
content:
application/json:
examples:
subsetAB:
description: With A and B
value:
a: 1
b: 2
subsetAC:
description: With A and C
value:
a: 1
c: 3
...
components:
schemas:
com.myservice.api.v42.Subset:
type: object
I have examples for input and output and can also see them nicely displayed in the /swagger-ui.html endpoint. However, the schema definition is still empty. And it would be convenient to just define and reference the schemas and have the examples generated automatically.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
