-
-
Notifications
You must be signed in to change notification settings - Fork 6.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] OpenAPI Generator fails to generate array models #7802
Comments
👍 Thanks for opening this issue! The team will review the labels and make any necessary changes. |
Did you try setting the |
It then generates models with just a plain diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java
index 24f407c08a..de212afa58 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java
@@ -26,6 +26,7 @@ import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
+import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.security.*;
@@ -482,9 +483,11 @@ public class DefaultGenerator implements Generator {
continue;
}
} else if (ModelUtils.isArraySchema(schema)) { // check to see if it's an "array" model
- if (!ModelUtils.isGenerateAliasAsModel(schema) && (schema.getProperties() == null || schema.getProperties().isEmpty())) {
- // schema without property, i.e. alias to array
- LOGGER.info("Model {} not generated since it's an alias to array (without property) and `generateAliasAsModel` is set to false (default)", name);
+ if (!ModelUtils.isGenerateAliasAsModel(schema) && (((ArraySchema) schema).getItems() == null ||
+ (!ModelUtils.isComposedSchema(((ArraySchema) schema).getItems()) &&
+ ((ArraySchema) schema).getItems().getProperties() == null || ((ArraySchema) schema).getItems().getProperties().isEmpty()))) {
+ // schema without items, i.e. alias to array
+ LOGGER.info("Model {} not generated since it's an alias to array (without items) and `generateAliasAsModel` is set to false (default)", name);
continue;
}
} But that only fixes it so that it isn't wrongly detected as an alias model. The inner |
Hi All, I believe this bug is causing my Apex code not to compile. Like @segevfiner I get the This error appears to originate from an attribute (not sure if that's the term?) in one of the API schemas (Open API 3.0):
Setting It looks like the code generator is interpreting the |
Any news? |
A colleague and I were able to reproduce this with This use case seems to be right out of the Swagger examples (i.e. array of objects), so it seems odd that this error would arise with recent builds given it's likely a common/typical use case in OpenAPI-generated APIs/specs.
Edit: nope: using the |
Hello, I tested this with openapi-generator-cli-5.1.0-20210108.143511-2.jar I used this command: java -jar openapi-generator-cli-5.1.0-20210108.143511-2.jar generate -g python-flask -i test.yaml -o test_schema/ --generate-alias-as-model --additional-properties packageName=test ... with test.yaml as input. It's an example using the array type, which contains object types (this example is built following the examples from swagger.io for OpenAPI 3.0) The warning message went away and the generator did generate a model in the following folder The dictionary types are empty: def __init__(self): # noqa: E501
"""TestSchema - a model defined in OpenAPI
"""
self.openapi_types = {
}
self.attribute_map = {
} I also created another example (using an example from here using just an object, not an array of objects, and the results I get match what I expected. I used test_object.yaml as input and this is the resulting model: test_schema.py The command used: java -jar openapi-generator-cli-5.1.0-20210108.143511-2.jar generate -g python-flask -i test_object.yaml -o test_object/ --additional-properties packageName=test In this instance, the OpenAPI Generator successfully populated the model with the fields, getters and setters for them. Here is the constructor for the object: def __init__(self, id=None, username=None, name=None): # noqa: E501
"""TestSchema - a model defined in OpenAPI
:param id: The id of this TestSchema. # noqa: E501
:type id: int
:param username: The username of this TestSchema. # noqa: E501
:type username: str
:param name: The name of this TestSchema. # noqa: E501
:type name: str
"""
self.openapi_types = {
'id': int,
'username': str,
'name': str
}
self.attribute_map = {
'id': 'id',
'username': 'username',
'name': 'name'
}
self._id = id
self._username = username
self._name = name How should I best proceed to be able to generate a non-empty schema for the array-of-objects use case? |
@keysight-diana-belmega Thanks for putting this MCVE/PoC together Diana! |
Same issue here with Docker 1.41 spec of |
Hello! I found a workaround so that the OpenAPI generator generates valid models when an array is needed. I tried to wrap the array in a top-level object, like in this example input file test_wrapper.yaml. You can see that the wrapper object is the only difference from my original example and the OpenAPI generator successfully created a good model, without using the This worked with openapi-generator-cli-5.1.0-20210108.143511-2.jar. I didn't try it with other versions of the generator. The command I used is: java -jar openapi-generator-cli-5.1.0-20210108.143511-2.jar generate -g python-flask -i test_wrapper.yaml -o test_wrapper_schema/ --additional-properties packageName=test ...with test_wrapper.yaml as input file. The files generated in the You can see that test_schema.py contains a Python list of the generated object test_schema_array_wrapper.py, so it managed to create an object that contains the desired array: def __init__(self, array_wrapper=None): # noqa: E501
"""TestSchema - a model defined in OpenAPI
:param array_wrapper: The array_wrapper of this TestSchema. # noqa: E501
:type array_wrapper: List[TestSchemaArrayWrapper]
"""
self.openapi_types = {
'array_wrapper': List[TestSchemaArrayWrapper]
}
self.attribute_map = {
'array_wrapper': 'array-wrapper'
}
self._array_wrapper = array_wrapper I don't know if this workaround works for any use-case, but I hope it helps anyone who needs it and maybe aids in solving the bug. Thanks! |
This is applicable for typescript-angular generator as well. |
Same for PHP clients |
Same for Java Client |
currently for generated spring boot controller that returns a list:
The example response is not a list of 1 object, or a list of examples, but it's a single object which is wrong. |
Another dirty hack to get the generator to behave, at least on Node, is just to add Array's built-in
|
Can confirm this also worked with Springboot |
It's not a hack when you depend on an external yaml url whose another team is in charge of, and have no possible way of making them change "on the fly" declaration of inner items, to a dedicated new named schema through 1 year and a half and still not fixed... it's always worked with |
i need to generate the array component, because i am using a Mapper to convert my classes in SpringBoot, and my response need to be an Array, cause the method findAll() that im using on ClassService.Java requires an Array, my ResponseEntity also requires an array and nothing worked :( |
This generates a model with the length property only. and nothing else. components:
schemas:
Cat:
type: object
required:
- id
- name
properties:
id:
type: integer
name:
type: string
description:
type: string
status:
type: string
enum:
- available
- adopted
- dead
Cats:
type: array
properties:
length:
type: integer
items:
$ref: '#/components/schemas/Cat' Cats.java package org.openapitools.model;
import java.net.URI;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import java.util.Arrays;
import org.openapitools.jackson.nullable.JsonNullable;
import java.util.NoSuchElementException;
import org.openapitools.jackson.nullable.JsonNullable;
import java.time.OffsetDateTime;
import javax.validation.Valid;
import javax.validation.constraints.*;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.*;
import javax.annotation.Generated;
/**
* Cats
*/
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-12-06T13:01:52.635460+05:30[Asia/Kolkata]")
public class Cats {
@JsonProperty("length")
private JsonNullable<Object> length = JsonNullable.undefined();
public Cats length(Object length) {
this.length = JsonNullable.of(length);
return this;
}
/**
* Get length
* @return length
*/
@Schema(name = "length", required = false)
public JsonNullable<Object> getLength() {
return length;
}
public void setLength(JsonNullable<Object> length) {
this.length = length;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Cats cats = (Cats) o;
return equalsNullable(this.length, cats.length);
}
private static <T> boolean equalsNullable(JsonNullable<T> a, JsonNullable<T> b) {
return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get()));
}
@Override
public int hashCode() {
return Objects.hash(hashCodeNullable(length));
}
private static <T> int hashCodeNullable(JsonNullable<T> a) {
if (a == null) {
return 1;
}
return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Cats {\n");
sb.append(" length: ").append(toIndentedString(length)).append("\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
} Am I missing anything else that I should add? |
Any news on this issue? Still applicable in 2023. EDIT: TranslatedField:
type: array
items:
$ref: "#/components/schemas/TranslatedFieldItem"
TranslatedFieldItem:
type: object
required:
- value
properties:
lang:
$ref: "#/components/schemas/Language"
value:
type: string |
Can confirm this for typescript-fetch generator as well |
Can confirm this also worked with Springboot |
Any update on this? Experiencing the same issue with |
Also happening with Python, FastAPI and Pydantic v2. the generator worked correctly with the previous version of Pydantic though. Any thoughts? |
run into this issue aswell for rust |
Still seems to be present in v7.2.0 while generating arrays/lists in C#. Any updates? |
If you want array models to work without any special configuration you can try using the python and Java generators here which is a descendant of this code base |
Any updates? |
Running into this issue as well for Dart |
Bug Report Checklist
Description
OpenAPI generator fails to generate array models. It complains with:
openapi-generator version
v4.3.1
And also tried latest master using Docker 07c23f4.
OpenAPI declaration file content or url
Generation Details
Steps to reproduce
Related issues/PRs
Suggest a fix
The following code is erroneous. An array has
items
notproperties
(Even required by the OpenAPI spec). You might need to castSchema
toArraySchema
to get access to items or something like that.openapi-generator/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java
Lines 485 to 488 in 41851b4
The text was updated successfully, but these errors were encountered: