I can sucessfully generate Spring API and model files using gradle, OpenApi generator plugin ("org.openapi.generator" version "4.2.1"
).
I have a single api.yml
file:
openapi: 3.0.2
info:
title: API Documentation
version: 1.0.0
servers:
- url: http://localhost:8080/
tags:
- name: Users
paths:
/users:
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Parent'
responses:
200:
description: New user created
components:
schemas:
Parent:
required:
- status
properties:
status:
type: string
discriminator:
propertyName: status
mapping:
CHILD_ONE: '#/components/schemas/ChildOne'
CHILD_TWO: '#/components/schemas/ChildTwo'
ChildOne:
allOf:
- $ref: '#/components/schemas/Parent'
- type: object
ChildTwo:
allOf:
- $ref: '#/components/schemas/Parent'
- type: object
And code generation produces Java Spring interface file and 3 model files: Parent.java
, ChildOne.java
and ChildTwo.java
- 2 children classes extend the Parent
class as expected.
However, when I split api.yml
into 2 files (see below), ChildOne.java
and ChildTwo.java
are completely missing (there is only Parent.java
file generated):
api.yml
file:
openapi: 3.0.2
info:
title: API Documentation
version: 1.0.0
servers:
- url: http://localhost:8080/
paths:
/users:
$ref: './api-sub.yml#/test'
api-sub.yml file:
test:
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Parent'
responses:
200:
description: New user created
components:
schemas:
Parent:
required:
- status
properties:
status:
type: string
discriminator:
propertyName: status
mapping:
CHILD_ONE: '#/components/schemas/ChildOne'
CHILD_TWO: '#/components/schemas/ChildTwo'
ChildOne:
allOf:
- $ref: '#/components/schemas/Parent'
- type: object
ChildTwo:
allOf:
- $ref: '#/components/schemas/Parent'
- type: object
Generation passes without errors but only 1 class - Parent.java
is generated:
// [...]
// Imports etc....
// [...]
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "status", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = ChildOne.class, name = "CHILD_ONE"),
@JsonSubTypes.Type(value = ChildTwo.class, name = "CHILD_TWO"),
})
public class Parent {
@JsonProperty("status")
private String status;
// [...]
// Getters, setters etc....
// [...]
Why 2 other classes ChildOne.java
and ChildTwo.java
are not generated?
Please note that generator is seeing them as it uses their names and mappings in Parent.java
.
I did some investigations and I've noticed that when I move schema definitions from api-sub.yml
into api.yml
like this:
api.yml
file:
openapi: 3.0.2
info:
title: API Documentation
version: 1.0.0
servers:
- url: http://localhost:8080/
paths:
/users:
$ref: './api-sub.yml#/test'
components:
schemas:
Parent:
required:
- status
properties:
status:
type: string
discriminator:
propertyName: status
mapping:
CHILD_ONE: '#/components/schemas/ChildOne'
CHILD_TWO: '#/components/schemas/ChildTwo'
ChildOne:
allOf:
- $ref: '#/components/schemas/Parent'
- type: object
ChildTwo:
allOf:
- $ref: '#/components/schemas/Parent'
- type: object
api-sub.yml
file:
test:
post:
requestBody:
content:
application/json:
schema:
$ref: 'api.yml#/components/schemas/Parent'
responses:
200:
description: New user created
Then, 4 files are generated: Parent.java
, ChildOne.java
, ChildTwo.java
and (surprise) Parent2.java
.
Parent2.java
is semantically the same as Parent.java
, just different name.
Any idea why is it so? Is there are bug in OpenApi generator?
Edit:
Yet another observation:
When I use a child somewhere in any endpoint e.g. (just for testing) in response, then this particular child is generated (but not the other one):
test:
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Parent'
responses:
200:
description: New user created
content:
application/json:
schema:
$ref: '#/components/schemas/ChildOne'
### [...]
### rest of api-sub.yml with schemas
### [...]
Does the child entity needs to be used to be generated? I've noticed such a behavior somewhere else beside of inheritance case.