With org.openapitools:openapi-generator-maven-plugin
, I have noticed that using allOf
composed of multiple objects in a response does not generate a class combining these multiple objects. Instead it uses the first class defined in the allOf
section.
Here is a minimal example (openapi.yaml
) :
openapi: 3.0.0
info:
title: Test
version: v1
paths:
/test:
get:
operationId: get
responses:
'200':
description: Get
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/A'
- $ref: '#/components/schemas/B'
components:
schemas:
A:
type: object
properties:
attA:
type: string
B:
type: object
properties:
attB:
type: integer
When generating the classes in Java via :
mvn org.openapitools:openapi-generator-maven-plugin:5.2.0:generate \
-Dopenapi.generator.maven.plugin.inputSpec=openapi.yaml \
-Dopenapi.generator.maven.plugin.generatorName=java
It shows a warning:
[WARNING] allOf with multiple schemas defined. Using only the first one: A
As expected, it generates classes A and B. But, when calling get()
, the value returned by the call is of type A
:
DefaultApi api = new DefaultApi();
A a = api.get();
Instead, I would have expected a composite object containing A
and B
properties (attA
and attB
), like this (result from https://editor.swagger.io/):
I have created an issue on GitHub, but hopefully someone here may have had the same issue and managed to fix it.
Also, I can't modify the openapi.yaml
file because it's an OpenAPI spec provided by an API I have to call, so modifying it would make no sense and will make it so difficult to manage if their OpenAPI spec change over time.
Version 6.0.0 of openapi-generator-maven-plugin
solves the issue by generating a class (Get200Response
) composed of the two objects A
and B
. After generating the classes using:
mvn org.openapitools:openapi-generator-maven-plugin:6.0.0:generate \
-Dopenapi.generator.maven.plugin.inputSpec=openapi.yaml \
-Dopenapi.generator.maven.plugin.generatorName=java
I can see that new Get200Response
class:
package org.openapitools.client.model;
// ...
public class Get200Response {
public static final String SERIALIZED_NAME_ATT_A = "attA";
@SerializedName(SERIALIZED_NAME_ATT_A)
private String attA;
public static final String SERIALIZED_NAME_ATT_B = "attB";
@SerializedName(SERIALIZED_NAME_ATT_B)
private Integer attB;
// ...
}
And I was able to make the following code work. In that example, I have a dummy webserver listening on port 5000
and defining a /test
endpoint returning {"attA": "hello", "attB": 1}
.
package org.example;
import org.openapitools.client.ApiClient;
import org.openapitools.client.ApiException;
import org.openapitools.client.api.DefaultApi;
import org.openapitools.client.model.Get200Response;
public class Main {
public static void main(String[] args) throws ApiException {
ApiClient apiClient = new ApiClient();
apiClient.setBasePath("http://localhost:5000");
DefaultApi api = new DefaultApi(apiClient);
Get200Response r = api.get();
System.out.println(r.getAttA());
System.out.println(r.getAttB());
}
}
This successfully prints:
hello
1