Skip to content
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

Better handling of API response in 3.1 spec #16986

Merged
merged 3 commits into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@
./bin/generate-samples.sh ./bin/configs/*.yaml
./bin/utils/export_docs_generators.sh
```
(For Windows users, please run the script in [Git BASH](https://gitforwindows.org/))
Commit all changed files.
This is important, as CI jobs will verify _all_ generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example `./bin/generate-samples.sh bin/configs/java*`.
For Windows users, please run the script in [Git BASH](https://gitforwindows.org/).

Do **NOT** purge any folders (e.g. tests) when regenerating the samples.

IMPORTANT: Do **NOT** purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
- [ ] File the PR against the [correct branch](https://github.com/OpenAPITools/openapi-generator/wiki/Git-Branches): `master` (upcoming 7.1.0 minor release - breaking changes with fallbacks), `8.0.x` (breaking changes without fallbacks)
- [ ] If your PR is targeting a particular programming language, @mention the [technical committee](https://github.com/openapitools/openapi-generator/#62---openapi-generator-technical-committee) members, so they are more likely to review the pull request.
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,7 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
if (op.getValue().getResponses() != null) {
for (Map.Entry<String, ApiResponse> ar : op.getValue().getResponses().entrySet()) {
ApiResponse a = ModelUtils.getReferencedApiResponse(openAPI, ar.getValue());
Schema responseSchema = ModelUtils.getSchemaFromResponse(a);
Schema responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(openAPI, a));
if (responseSchema != null) {
schemas.put(opId + ar.getKey(), responseSchema);
}
Expand Down Expand Up @@ -4379,7 +4379,7 @@ protected void handleMethodResponse(Operation operation,
CodegenOperation op,
ApiResponse methodResponse,
Map<String, String> schemaMappings) {
Schema responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(methodResponse));
Schema responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(openAPI, methodResponse));

if (responseSchema != null) {
CodegenProperty cm = fromProperty("response", responseSchema, false);
Expand Down Expand Up @@ -4813,6 +4813,7 @@ public CodegenResponse fromResponse(String responseCode, ApiResponse response) {
} else {
r.code = responseCode;
switch (r.code.charAt(0)) {

case '1':
r.is1xx = true;
break;
Expand All @@ -4835,12 +4836,11 @@ public CodegenResponse fromResponse(String responseCode, ApiResponse response) {

Schema responseSchema;
if (this.openAPI != null && this.openAPI.getComponents() != null) {
responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(response));
responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(openAPI, response));
} else { // no model/alias defined
responseSchema = ModelUtils.getSchemaFromResponse(response);
responseSchema = ModelUtils.getSchemaFromResponse(openAPI, response);
}
r.schema = responseSchema;

r.message = escapeText(response.getDescription());
// TODO need to revise and test examples in responses
// ApiResponse does not support examples at the moment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ void normalize() {
}

normalizePaths();
normalizeComponents();
normalizeComponentsSchemas();
normalizeComponentsResponses();
}

/**
Expand Down Expand Up @@ -346,7 +347,7 @@ private void normalizeHeaders(Map<String, Header> headers) {
/**
* Normalizes schemas in components
*/
private void normalizeComponents() {
private void normalizeComponentsSchemas() {
Map<String, Schema> schemas = openAPI.getComponents().getSchemas();
if (schemas == null) {
return;
Expand All @@ -364,6 +365,33 @@ private void normalizeComponents() {
}
}

/**
* Normalizes responses in components
*/
private void normalizeComponentsResponses() {
Map<String, ApiResponse> schemas = openAPI.getComponents().getResponses();
if (schemas == null) {
return;
}

List<String> schemaNames = new ArrayList<String>(schemas.keySet());
for (String schemaName : schemaNames) {
ApiResponse schema = schemas.get(schemaName);
if (schema == null) {
LOGGER.warn("{} not fount found in openapi/components/schemas.", schemaName);
} else {
Content content = ModelUtils.getReferencedApiResponse(openAPI, schema).getContent();
if (content == null || content.isEmpty()) {
continue;
}
for (Map.Entry<String, MediaType> entry : content.entrySet()) {
Schema entryResult = normalizeSchema(entry.getValue().getSchema(), new HashSet<>());
entry.getValue().setSchema(entryResult);
}
}
}
}

/**
* Normalizes a schema
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
if (op.getHasExamples()) {
// prepare examples for Apex test classes
ApiResponse apiResponse = findMethodResponse(operation.getResponses());
final Schema responseSchema = ModelUtils.getSchemaFromResponse(apiResponse);
final Schema responseSchema = ModelUtils.getSchemaFromResponse(openAPI, apiResponse);
String deserializedExample = toExampleValue(responseSchema);
for (Map<String, String> example : op.examples) {
example.put("example", escapeText(example.get("example")));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
ApiResponse apiResponse = findMethodResponse(operation.getResponses());

if (apiResponse != null) {
Schema response = ModelUtils.getSchemaFromResponse(apiResponse);
Schema response = ModelUtils.getSchemaFromResponse(openAPI, apiResponse);
if (response != null) {
CodegenProperty cm = fromProperty("response", response, false);
op.vendorExtensions.put("x-codegen-response", cm);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
ApiResponse methodResponse = findMethodResponse(operation.getResponses());

if (methodResponse != null) {
Schema response = ModelUtils.getSchemaFromResponse(methodResponse);
Schema response = ModelUtils.getSchemaFromResponse(openAPI, methodResponse);
response = unaliasSchema(response);
if (response != null) {
CodegenProperty cm = fromProperty("response", response, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ public ExtendedCodegenOperation fromOperation(String path, String httpMethod, Op
}

if (!op.hasReturnPassthroughVoid) {
Schema responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(methodResponse));
Schema responseSchema = unaliasSchema(ModelUtils.getSchemaFromResponse(openAPI, methodResponse));
ExtendedCodegenProperty cp = null;
if (op.returnPassthrough instanceof String && cm != null) {
cp = (ExtendedCodegenProperty) this.processCodeGenModel(cm).vars.get(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1009,11 +1009,12 @@ public static Schema getSchemaFromRequestBody(RequestBody requestBody) {
/**
* Return the first defined Schema for a ApiResponse
*
* @param openAPI OpenAPI spec.
* @param response api response of the operation
* @return firstSchema
*/
public static Schema getSchemaFromResponse(ApiResponse response) {
return getSchemaFromContent(response.getContent());
public static Schema getSchemaFromResponse(OpenAPI openAPI, ApiResponse response) {
return getSchemaFromContent(getReferencedApiResponse(openAPI, response).getContent());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #17003 with better null check

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,36 @@ paths:
description: User not found
security:
- api_key: []
/no_ref:
get:
operationId: response_no_ref
tags:
- fake
responses:
'200':
description: required to pass validation
content:
text/plain:
schema:
type: string

/ref/no_ref:
get:
operationId: response_ref_to_no_ref
tags:
- fake
responses:
'200':
$ref: '#/components/responses/no_ref'

/ref/ref:
get:
operationId: response_ref_to_ref
tags:
- fake
responses:
'200':
$ref: '#/components/responses/ref'
externalDocs:
description: Find out more about Swagger
url: 'http://swagger.io'
Expand All @@ -593,6 +623,20 @@ components:
$ref: '#/components/schemas/Pet'
description: Pet object that needs to be added to the store
required: true
responses:
no_ref:
description: required to pass validation
content:
text/plain:
schema:
type: string

ref:
description: required to pass validation
content:
text/plain:
schema:
$ref: '#/components/schemas/simple_text'
securitySchemes:
petstore_auth:
type: oauth2
Expand Down Expand Up @@ -773,3 +817,5 @@ components:
color:
type: string
default: red
simple_text:
type: string
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ docs/Animal.md
docs/Cat.md
docs/Category.md
docs/Dog.md
docs/FakeApi.md
docs/ModelApiResponse.md
docs/OneOfStringOrInt.md
docs/Order.md
Expand Down Expand Up @@ -41,6 +42,7 @@ src/main/java/org/openapitools/client/ProgressResponseBody.java
src/main/java/org/openapitools/client/ServerConfiguration.java
src/main/java/org/openapitools/client/ServerVariable.java
src/main/java/org/openapitools/client/StringUtil.java
src/main/java/org/openapitools/client/api/FakeApi.java
src/main/java/org/openapitools/client/api/PetApi.java
src/main/java/org/openapitools/client/api/StoreApi.java
src/main/java/org/openapitools/client/api/UserApi.java
Expand Down
17 changes: 7 additions & 10 deletions samples/client/petstore/java/okhttp-gson-3.1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,20 @@ Please follow the [installation](#installation) instruction and execute the foll
import org.openapitools.client.ApiClient;
import org.openapitools.client.ApiException;
import org.openapitools.client.Configuration;
import org.openapitools.client.auth.*;
import org.openapitools.client.models.*;
import org.openapitools.client.api.PetApi;
import org.openapitools.client.api.FakeApi;

public class Example {
public static void main(String[] args) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("http://petstore.swagger.io/v2");

// Configure OAuth2 access token for authorization: petstore_auth
OAuth petstore_auth = (OAuth) defaultClient.getAuthentication("petstore_auth");
petstore_auth.setAccessToken("YOUR ACCESS TOKEN");

PetApi apiInstance = new PetApi(defaultClient);
Pet pet = new Pet(); // Pet | Pet object that needs to be added to the store
FakeApi apiInstance = new FakeApi(defaultClient);
try {
Pet result = apiInstance.addPet(pet);
String result = apiInstance.responseNoRef();
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling PetApi#addPet");
System.err.println("Exception when calling FakeApi#responseNoRef");
System.err.println("Status code: " + e.getCode());
System.err.println("Reason: " + e.getResponseBody());
System.err.println("Response headers: " + e.getResponseHeaders());
Expand All @@ -118,6 +112,9 @@ All URIs are relative to *http://petstore.swagger.io/v2*

Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
*FakeApi* | [**responseNoRef**](docs/FakeApi.md#responseNoRef) | **GET** /no_ref |
*FakeApi* | [**responseRefToNoRef**](docs/FakeApi.md#responseRefToNoRef) | **GET** /ref/no_ref |
*FakeApi* | [**responseRefToRef**](docs/FakeApi.md#responseRefToRef) | **GET** /ref/ref |
*PetApi* | [**addPet**](docs/PetApi.md#addPet) | **POST** /pet | Add a new pet to the store
*PetApi* | [**deletePet**](docs/PetApi.md#deletePet) | **DELETE** /pet/{petId} | Deletes a pet
*PetApi* | [**findPetsByStatus**](docs/PetApi.md#findPetsByStatus) | **GET** /pet/findByStatus | Finds Pets by status
Expand Down
46 changes: 46 additions & 0 deletions samples/client/petstore/java/okhttp-gson-3.1/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,37 @@ paths:
- user
x-content-type: application/json
x-accepts: application/json
/no_ref:
get:
operationId: response_no_ref
responses:
"200":
content:
text/plain:
schema:
type: string
description: required to pass validation
tags:
- fake
x-accepts: text/plain
/ref/no_ref:
get:
operationId: response_ref_to_no_ref
responses:
"200":
$ref: '#/components/responses/no_ref'
tags:
- fake
x-accepts: text/plain
/ref/ref:
get:
operationId: response_ref_to_ref
responses:
"200":
$ref: '#/components/responses/ref'
tags:
- fake
x-accepts: text/plain
components:
requestBodies:
UserArray:
Expand All @@ -631,6 +662,19 @@ components:
$ref: '#/components/schemas/Pet'
description: Pet object that needs to be added to the store
required: true
responses:
no_ref:
content:
text/plain:
schema:
type: string
description: required to pass validation
ref:
content:
text/plain:
schema:
$ref: '#/components/schemas/simple_text'
description: required to pass validation
schemas:
Order:
description: An order for a pets from the pet store
Expand Down Expand Up @@ -833,6 +877,8 @@ components:
type: string
required:
- className
simple_text:
type: string
updatePetWithForm_request:
properties:
name:
Expand Down