diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java
index ef348bbb266..83413a9ee11 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java
@@ -29,7 +29,8 @@ public class CodegenOperation {
isArray, isMultipart,
isResponseBinary = false, isResponseFile = false, hasReference = false,
isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy,
- isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false;
+ isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false,
+ hasErrorResponseObject; // if 4xx, 5xx repsonses have at least one error object defined
public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType,
returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse;
public CodegenDiscriminator discriminator;
@@ -297,6 +298,7 @@ public class CodegenOperation {
sb.append(", isResponseFile=").append(isResponseFile);
sb.append(", hasReference=").append(hasReference);
sb.append(", hasDefaultResponse=").append(hasDefaultResponse);
+ sb.append(", hasErrorResponseObject=").append(hasErrorResponseObject);
sb.append(", isRestfulIndex=").append(isRestfulIndex);
sb.append(", isRestfulShow=").append(isRestfulShow);
sb.append(", isRestfulCreate=").append(isRestfulCreate);
@@ -371,6 +373,7 @@ public class CodegenOperation {
isResponseFile == that.isResponseFile &&
hasReference == that.hasReference &&
hasDefaultResponse == that.hasDefaultResponse &&
+ hasErrorResponseObject == that.hasErrorResponseObject &&
isRestfulIndex == that.isRestfulIndex &&
isRestfulShow == that.isRestfulShow &&
isRestfulCreate == that.isRestfulCreate &&
@@ -435,6 +438,7 @@ public class CodegenOperation {
produces, prioritizedContentTypes, servers, bodyParam, allParams, bodyParams, pathParams, queryParams,
headerParams, formParams, cookieParams, requiredParams, optionalParams, authMethods, tags,
responses, callbacks, imports, examples, requestBodyExamples, externalDocs, vendorExtensions,
- nickname, operationIdOriginal, operationIdLowerCase, operationIdCamelCase, operationIdSnakeCase);
+ nickname, operationIdOriginal, operationIdLowerCase, operationIdCamelCase, operationIdSnakeCase,
+ hasErrorResponseObject);
}
}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
index f1736f0e532..e97a6caf557 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
@@ -3976,6 +3976,12 @@ public class DefaultCodegen implements CodegenConfig {
if (Boolean.TRUE.equals(r.isFile) && Boolean.TRUE.equals(r.is2xx) && Boolean.FALSE.equals(op.isResponseFile)) {
op.isResponseFile = Boolean.TRUE;
}
+
+ // check if any 4xx or 5xx reponse has an error response object defined
+ if ((Boolean.TRUE.equals(r.is4xx) || Boolean.TRUE.equals(r.is5xx)) &&
+ Boolean.FALSE.equals(r.primitiveType) && Boolean.FALSE.equals(r.simpleType)) {
+ op.hasErrorResponseObject = Boolean.TRUE;
+ }
}
op.responses.sort((a, b) -> {
int aScore = a.isWildcard() ? 2 : a.isRange() ? 1 : 0;
@@ -4269,6 +4275,7 @@ public class DefaultCodegen implements CodegenConfig {
r.setComposedSchemas(getComposedSchemas(responseSchema));
if (ModelUtils.isArraySchema(responseSchema)) {
r.simpleType = false;
+ r.isArray = true;
r.containerType = cp.containerType;
ArraySchema as = (ArraySchema) responseSchema;
CodegenProperty items = fromProperty("response", getSchemaItems(as));
@@ -4324,6 +4331,8 @@ public class DefaultCodegen implements CodegenConfig {
} else if (ModelUtils.isTypeObjectSchema(responseSchema)) {
if (ModelUtils.isFreeFormObject(openAPI, responseSchema)) {
r.isFreeFormObject = true;
+ } else {
+ r.isModel = true;
}
r.simpleType = false;
r.containerType = cp.containerType;
@@ -4335,9 +4344,6 @@ public class DefaultCodegen implements CodegenConfig {
LOGGER.debug("Property type is not primitive: {}", cp.dataType);
}
- if (!r.isMap && !r.isArray) {
- r.simpleType = true;
- }
r.primitiveType = (r.baseType == null || languageSpecificPrimitives().contains(r.baseType));
if (r.baseType == null) {
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElixirClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElixirClientCodegen.java
index 9903908d4e0..62c9d6dcc5f 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElixirClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ElixirClientCodegen.java
@@ -613,7 +613,7 @@ public class ElixirClientCodegen extends DefaultCodegen implements CodegenConfig
return "%{}";
}
// Primitive return type, don't even try to decode
- if (baseType == null || (simpleType && primitiveType)) {
+ if (baseType == null || (containerType == null && primitiveType)) {
return "false";
} else if (isArray && languageSpecificPrimitives().contains(baseType)) {
return "[]";
@@ -733,16 +733,13 @@ public class ElixirClientCodegen extends DefaultCodegen implements CodegenConfig
StringBuilder returnEntry = new StringBuilder();
if (exResponse.baseType == null) {
returnEntry.append("nil");
- } else if (exResponse.simpleType) {
+ } else if (exResponse.containerType == null) { // not container (array, map, set)
if (!exResponse.primitiveType) {
returnEntry.append(moduleName);
returnEntry.append(".Model.");
}
returnEntry.append(exResponse.baseType);
returnEntry.append(".t");
- } else if (exResponse.containerType == null) {
- returnEntry.append(returnBaseType);
- returnEntry.append(".t");
} else {
if (exResponse.containerType.equals("array") ||
exResponse.containerType.equals("set")) {
diff --git a/modules/openapi-generator/src/main/resources/asciidoc-documentation/index.mustache b/modules/openapi-generator/src/main/resources/asciidoc-documentation/index.mustache
index 48d810d038a..483ee5870f4 100644
--- a/modules/openapi-generator/src/main/resources/asciidoc-documentation/index.mustache
+++ b/modules/openapi-generator/src/main/resources/asciidoc-documentation/index.mustache
@@ -104,7 +104,7 @@ Operation Id:: {{nickname}}
| {{code}}
| {{message}}
-| {{^simpleType}}{{dataType}}[<<{{baseType}}>>]{{/simpleType}} {{#simpleType}}<<{{dataType}}>>{{/simpleType}}
+| {{#containerType}}{{dataType}}[<<{{baseType}}>>]{{/containerType}} {{^containerType}}<<{{dataType}}>>{{/containerType}}
{{/responses}}
|===
diff --git a/modules/openapi-generator/src/main/resources/htmlDocs/index.mustache b/modules/openapi-generator/src/main/resources/htmlDocs/index.mustache
index a5ad68cc9c8..2f3f276c476 100644
--- a/modules/openapi-generator/src/main/resources/htmlDocs/index.mustache
+++ b/modules/openapi-generator/src/main/resources/htmlDocs/index.mustache
@@ -134,7 +134,7 @@
{{#responses}}
{{code}}
{{message}}
- {{#simpleType}}{{dataType}}{{/simpleType}}
+ {{^containerType}}{{dataType}}{{/containerType}}
{{#examples}}
Example data
Content-Type: {{{contentType}}}
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java
index 87486da4c36..949bc1a9243 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java
@@ -3877,6 +3877,59 @@ public class DefaultCodegenTest {
}
@Test
+ public void testResponses() {
+ final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/response-tests.yaml");
+ final DefaultCodegen codegen = new DefaultCodegen();
+ codegen.setOpenAPI(openAPI);
+ codegen.setDisallowAdditionalPropertiesIfNotPresent(false);
+
+ String path;
+ Operation operation;
+ CodegenOperation co;
+ CodegenParameter cpa;
+ CodegenResponse cr;
+
+ path = "/pet/{petId}";
+ operation = openAPI.getPaths().get(path).getGet();
+ co = codegen.fromOperation(path, "GET", operation, null);
+ //assertTrue(co.hasErrorResponseObject);
+ cr = co.responses.get(0);
+ assertTrue(cr.is2xx);
+ assertFalse(cr.simpleType);
+ assertFalse(cr.primitiveType);
+ cr = co.responses.get(3);
+ assertTrue(cr.is5xx);
+ assertFalse(cr.simpleType);
+ assertFalse(cr.primitiveType);
+
+ path = "/pet";
+ operation = openAPI.getPaths().get(path).getPut();
+ co = codegen.fromOperation(path, "PUT", operation, null);
+ assertTrue(co.hasErrorResponseObject);
+
+ // 200 response
+ cr = co.responses.get(0);
+ assertTrue(cr.is2xx);
+ assertFalse(cr.simpleType);
+ assertFalse(cr.primitiveType);
+
+ // 400 response
+ cr = co.responses.get(1);
+ assertTrue(cr.is4xx);
+ assertEquals(cr.code, "400");
+ assertFalse(cr.simpleType);
+ assertFalse(cr.primitiveType);
+
+ path = "/pet/findByTags";
+ operation = openAPI.getPaths().get(path).getGet();
+ co = codegen.fromOperation(path, "GET", operation, null);
+ assertFalse(co.hasErrorResponseObject);
+ cr = co.responses.get(0);
+ assertTrue(cr.is2xx);
+ assertFalse(cr.simpleType);
+ assertFalse(cr.primitiveType);
+ }
+
public void testParameterContent() {
DefaultCodegen codegen = new DefaultCodegen();
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/content-data.yaml");
diff --git a/modules/openapi-generator/src/test/resources/3_0/response-tests.yaml b/modules/openapi-generator/src/test/resources/3_0/response-tests.yaml
new file mode 100644
index 00000000000..e17881606db
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_0/response-tests.yaml
@@ -0,0 +1,571 @@
+openapi: 3.0.0
+servers:
+ - url: 'http://petstore.swagger.io/v2'
+info:
+ description: >-
+ This is a sample server Petstore server. For this sample, you can use the api key
+ `special-key` to test the authorization filters.
+ version: 1.0.0
+ title: OpenAPI Petstore
+ license:
+ name: Apache-2.0
+ url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
+tags:
+ - name: pet
+ description: Everything about your Pets
+ - name: store
+ description: Access to Petstore orders
+ - name: user
+ description: Operations about user
+paths:
+ /pet:
+ post:
+ tags:
+ - pet
+ summary: Add a new pet to the store
+ description: ''
+ operationId: addPet
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ '405':
+ description: Invalid input
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ requestBody:
+ $ref: '#/components/requestBodies/Pet'
+ put:
+ tags:
+ - pet
+ summary: Update an existing pet
+ description: ''
+ operationId: updatePet
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ '400':
+ description: Invalid ID supplied
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApiResponse'
+ '404':
+ description: Pet not found
+ '405':
+ description: Validation exception
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ requestBody:
+ $ref: '#/components/requestBodies/Pet'
+ /pet/findByStatus:
+ get:
+ tags:
+ - pet
+ summary: Finds Pets by status
+ description: Multiple status values can be provided with comma separated strings
+ operationId: findPetsByStatus
+ parameters:
+ - name: status
+ in: query
+ description: Status values that need to be considered for filter
+ required: true
+ style: form
+ explode: false
+ deprecated: true
+ schema:
+ type: array
+ items:
+ type: string
+ enum:
+ - available
+ - pending
+ - sold
+ default: available
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Pet'
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Pet'
+ '400':
+ description: Invalid status value
+ security:
+ - petstore_auth:
+ - 'read:pets'
+ /pet/findByTags:
+ get:
+ tags:
+ - pet
+ summary: Finds Pets by tags
+ description: >-
+ Multiple tags can be provided with comma separated strings. Use tag1,
+ tag2, tag3 for testing.
+ operationId: findPetsByTags
+ parameters:
+ - name: tags
+ in: query
+ description: Tags to filter by
+ required: true
+ style: form
+ explode: false
+ schema:
+ type: array
+ items:
+ type: string
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Pet'
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/Pet'
+ '400':
+ description: Invalid tag value
+ security:
+ - petstore_auth:
+ - 'read:pets'
+ deprecated: true
+ '/pet/{petId}':
+ get:
+ tags:
+ - pet
+ summary: Find pet by ID
+ description: Returns a single pet
+ operationId: getPetById
+ parameters:
+ - name: petId
+ in: path
+ description: ID of pet to return
+ required: true
+ schema:
+ type: integer
+ format: int64
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ '400':
+ description: Invalid ID supplied
+ '404':
+ description: Pet not found
+ '500':
+ description: Server error
+ content:
+ application/application:
+ schema:
+ $ref: '#/components/schemas/ApiResponse'
+ security:
+ - api_key: []
+ post:
+ tags:
+ - pet
+ summary: Updates a pet in the store with form data
+ description: ''
+ operationId: updatePetWithForm
+ parameters:
+ - name: petId
+ in: path
+ description: ID of pet that needs to be updated
+ required: true
+ schema:
+ type: integer
+ format: int64
+ responses:
+ '405':
+ description: Invalid input
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ requestBody:
+ content:
+ application/x-www-form-urlencoded:
+ schema:
+ type: object
+ properties:
+ name:
+ description: Updated name of the pet
+ type: string
+ status:
+ description: Updated status of the pet
+ type: string
+ delete:
+ tags:
+ - pet
+ summary: Deletes a pet
+ description: ''
+ operationId: deletePet
+ parameters:
+ - name: api_key
+ in: header
+ required: false
+ schema:
+ type: string
+ - name: petId
+ in: path
+ description: Pet id to delete
+ required: true
+ schema:
+ type: integer
+ format: int64
+ responses:
+ '400':
+ description: Invalid pet value
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ '/pet/{petId}/uploadImage':
+ post:
+ tags:
+ - pet
+ summary: uploads an image
+ description: ''
+ operationId: uploadFile
+ parameters:
+ - name: petId
+ in: path
+ description: ID of pet to update
+ required: true
+ schema:
+ type: integer
+ format: int64
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ApiResponse'
+ security:
+ - petstore_auth:
+ - 'write:pets'
+ - 'read:pets'
+ requestBody:
+ content:
+ multipart/form-data:
+ schema:
+ type: object
+ properties:
+ additionalMetadata:
+ description: Additional data to pass to server
+ type: string
+ file:
+ description: file to upload
+ type: string
+ format: binary
+ '/store/order/{orderId}':
+ get:
+ tags:
+ - store
+ summary: Find purchase order by ID
+ description: >-
+ For valid response try integer IDs with value <= 5 or > 10. Other values
+ will generated exceptions
+ operationId: getOrderById
+ parameters:
+ - name: orderId
+ in: path
+ description: ID of pet that needs to be fetched
+ required: true
+ schema:
+ type: integer
+ format: int64
+ minimum: 1
+ maximum: 5
+ responses:
+ '200':
+ description: successful operation
+ content:
+ application/xml:
+ schema:
+ $ref: '#/components/schemas/Order'
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Order'
+ '400':
+ description: Invalid ID supplied
+ '404':
+ description: Order not found
+ '500':
+ description: Server error
+ delete:
+ tags:
+ - store
+ summary: Delete purchase order by ID
+ description: >-
+ For valid response try integer IDs with value < 1000. Anything above
+ 1000 or nonintegers will generate API errors
+ operationId: deleteOrder
+ parameters:
+ - name: orderId
+ in: path
+ description: ID of the order that needs to be deleted
+ required: true
+ schema:
+ type: string
+ responses:
+ '400':
+ description: Invalid ID supplied
+ '404':
+ description: Order not found
+ /user/login:
+ get:
+ tags:
+ - user
+ summary: Logs user into the system
+ description: ''
+ operationId: loginUser
+ parameters:
+ - name: username
+ in: query
+ description: The user name for login
+ required: true
+ schema:
+ type: string
+ pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
+ - name: password
+ in: query
+ description: The password for login in clear text
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: successful operation
+ headers:
+ Set-Cookie:
+ description: >-
+ Cookie authentication key for use with the `api_key`
+ apiKey authentication.
+ schema:
+ type: string
+ example: AUTH_KEY=abcde12345; Path=/; HttpOnly
+ X-Rate-Limit:
+ description: calls per hour allowed by the user
+ schema:
+ type: integer
+ format: int32
+ X-Expires-After:
+ description: date in UTC when token expires
+ schema:
+ type: string
+ format: date-time
+ content:
+ application/xml:
+ schema:
+ type: string
+ application/json:
+ schema:
+ type: string
+ '400':
+ description: Invalid username/password supplied
+externalDocs:
+ description: Find out more about Swagger
+ url: 'http://swagger.io'
+components:
+ requestBodies:
+ UserArray:
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
+ description: List of user object
+ required: true
+ Pet:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ application/xml:
+ schema:
+ $ref: '#/components/schemas/Pet'
+ description: Pet object that needs to be added to the store
+ required: true
+ securitySchemes:
+ petstore_auth:
+ type: oauth2
+ flows:
+ implicit:
+ authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
+ scopes:
+ 'write:pets': modify pets in your account
+ 'read:pets': read your pets
+ api_key:
+ type: apiKey
+ name: api_key
+ in: header
+ schemas:
+ Order:
+ title: Pet Order
+ description: An order for a pets from the pet store
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ petId:
+ type: integer
+ format: int64
+ quantity:
+ type: integer
+ format: int32
+ shipDate:
+ type: string
+ format: date-time
+ status:
+ type: string
+ description: Order Status
+ enum:
+ - placed
+ - approved
+ - delivered
+ complete:
+ type: boolean
+ default: false
+ xml:
+ name: Order
+ Category:
+ title: Pet category
+ description: A category for a pet
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ pattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$'
+ xml:
+ name: Category
+ User:
+ title: a User
+ description: A User who is purchasing from the pet store
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ username:
+ type: string
+ firstName:
+ type: string
+ lastName:
+ type: string
+ email:
+ type: string
+ password:
+ type: string
+ phone:
+ type: string
+ userStatus:
+ type: integer
+ format: int32
+ description: User Status
+ xml:
+ name: User
+ Tag:
+ title: Pet Tag
+ description: A tag for a pet
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ xml:
+ name: Tag
+ Pet:
+ title: a Pet
+ description: A pet for sale in the pet store
+ type: object
+ required:
+ - name
+ - photoUrls
+ properties:
+ id:
+ type: integer
+ format: int64
+ category:
+ $ref: '#/components/schemas/Category'
+ name:
+ type: string
+ example: doggie
+ photoUrls:
+ type: array
+ xml:
+ name: photoUrl
+ wrapped: true
+ items:
+ type: string
+ tags:
+ type: array
+ xml:
+ name: tag
+ wrapped: true
+ items:
+ $ref: '#/components/schemas/Tag'
+ status:
+ type: string
+ description: pet status in the store
+ deprecated: true
+ enum:
+ - available
+ - pending
+ - sold
+ xml:
+ name: Pet
+ ApiResponse:
+ title: An uploaded response
+ description: Describes the result of uploading an image resource
+ type: object
+ properties:
+ code:
+ type: integer
+ format: int32
+ type:
+ type: string
+ message:
+ type: string