Skip to content

Commit

Permalink
feat (#19407 JAVA SPRING WEBCLIENT): Add support for useSingleRequest…
Browse files Browse the repository at this point in the history
…Parameter to Spring WebClient (#19827)

* chore (JAVA SPRING WEBCLIENT): Remove comments used for debugging

* feat (JAVA SPRING WEBCLIENT): Add support for useSingleRequestParameter to Spring WebClient

* feat (JAVA SPRING WEBCLIENT): Generate samples and docs

* fix (JAVA SPRING WEBCLIENT): Fix missing return error & Fix JDK17 action webclient useSingleRequestParameter test path

* fix (JAVA SPRING WEBCLIENT): Fix code indention

* fix (JAVA SPRING WEBCLIENT): Fix code indention again

* fix (JAVA SPRING WEBCLIENT): Update samples

* feat (JAVA SPRING WEBCLIENT): Regenerate after pull rebase
  • Loading branch information
Nicklas2751 authored Dec 15, 2024
1 parent cc40f40 commit 07d19ba
Show file tree
Hide file tree
Showing 240 changed files with 26,760 additions and 230 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/samples-java-client-jdk11.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ on:
- samples/client/others/java/okhttp-gson-oneOf-array/**
- samples/client/others/java/resttemplate-useAbstractionForFiles/**
- samples/client/others/java/webclient-useAbstractionForFiles/**
- samples/client/petstore/java/webclient-useSingleRequestParameter/**
- samples/client/others/java/jersey2-oneOf-duplicates/**
- samples/client/others/java/jersey2-oneOf-Mixed/**
- samples/client/others/java/resttemplate-list-schema-validation/**
Expand All @@ -31,6 +32,7 @@ on:
- samples/client/others/java/okhttp-gson-oneOf-array/**
- samples/client/others/java/resttemplate-useAbstractionForFiles/**
- samples/client/others/java/webclient-useAbstractionForFiles/**
- samples/client/petstore/java/webclient-useSingleRequestParameter/**
- samples/client/others/java/jersey2-oneOf-duplicates/**
- samples/client/others/java/jersey2-oneOf-Mixed/**
- samples/client/others/java/resttemplate-list-schema-validation/**
Expand All @@ -57,6 +59,7 @@ jobs:
- samples/client/petstore/java/webclient
- samples/client/petstore/java/webclient-nullable-arrays
- samples/client/petstore/java/webclient-swagger2
- samples/client/petstore/java/webclient-useSingleRequestParameter
- samples/client/petstore/java/vertx
- samples/client/petstore/java/jersey2-java8-localdatetime
- samples/client/petstore/java/google-api-client
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/samples-java-client-jdk17.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ on:
paths:
- samples/client/petstore/java/resttemplate-jakarta/**
- samples/client/petstore/java/webclient-jakarta/**
- samples/client/petstore/java/restclient-*/**
- samples/client/petstore/java/restclient-*/**
- samples/client/petstore/java/webclient-useSingleRequestParameter/**
pull_request:
paths:
- samples/client/petstore/java/resttemplate-jakarta/**
- samples/client/petstore/java/webclient-jakarta/**
- samples/client/petstore/java/restclient-*/**
- samples/client/petstore/java/webclient-useSingleRequestParameter/**
jobs:
build:
name: Build Java Client JDK17
Expand All @@ -26,6 +28,7 @@ jobs:
- samples/client/petstore/java/restclient-nullable-arrays
- samples/client/petstore/java/restclient-swagger2
- samples/client/petstore/java/restclient-useSingleRequestParameter
- samples/client/petstore/java/webclient-useSingleRequestParameter
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
Expand Down
9 changes: 9 additions & 0 deletions bin/configs/java-webclient-useSingleRequestParameter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
generatorName: java
outputDir: samples/client/petstore/java/webclient-useSingleRequestParameter
library: webclient
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml
templateDir: modules/openapi-generator/src/main/resources/Java
additionalProperties:
artifactId: singleparam-webclient
hideGenerationTimestamp: "true"
useSingleRequestParameter: true
2 changes: 1 addition & 1 deletion docs/generators/java-microprofile.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient support this option.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option.| |false|
|webclientBlockingOperations|Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync| |false|
|withAWSV4Signature|whether to include AWS v4 signature support (only available for okhttp-gson library)| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
Expand Down
2 changes: 1 addition & 1 deletion docs/generators/java.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|useRuntimeException|Use RuntimeException instead of Exception. Only jersey2, jersey3, okhttp-gson, vertx, microprofile support this option.| |false|
|useRxJava2|Whether to use the RxJava2 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useRxJava3|Whether to use the RxJava3 adapter with the retrofit2 library. IMPORTANT: This option has been deprecated.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient support this option.| |false|
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option.| |false|
|webclientBlockingOperations|Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync| |false|
|withAWSV4Signature|whether to include AWS v4 signature support (only available for okhttp-gson library)| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ public JavaClientCodegen() {
cliOptions.add(CliOption.newString(CONFIG_KEY_FROM_CLASS_NAME, "If true, set tag as key in @RegisterRestClient. Default to false. Only `microprofile` supports this option."));
cliOptions.add(CliOption.newBoolean(CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP, CodegenConstants.USE_ONEOF_DISCRIMINATOR_LOOKUP_DESC + " Only jersey2, jersey3, native, okhttp-gson support this option."));
cliOptions.add(CliOption.newString(MICROPROFILE_REST_CLIENT_VERSION, "Version of MicroProfile Rest Client API."));
cliOptions.add(CliOption.newBoolean(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, "Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient support this option."));
cliOptions.add(CliOption.newBoolean(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, "Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter. ONLY jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option."));
cliOptions.add(CliOption.newBoolean(WEBCLIENT_BLOCKING_OPERATIONS, "Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync", this.webclientBlockingOperations));
cliOptions.add(CliOption.newBoolean(GENERATE_CLIENT_AS_BEAN, "For resttemplate, configure whether to create `ApiClient.java` and Apis clients as bean (with `@Component` annotation).", this.generateClientAsBean));
cliOptions.add(CliOption.newBoolean(SUPPORT_URL_QUERY, "Generate toUrlQueryString in POJO (default to true). Available on `native`, `apache-httpclient` libraries."));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,6 @@ public class {{classname}} {
{{#operation}}
{{#useSingleRequestParameter}}
{{#hasParams}}
{{#hasSingleParam}}
// It has a single param!
/*
{{#allParams}}
* {{paramName}}
{{/allParams}}
*/
{{/hasSingleParam}}
{{^hasSingleParam}}
// It has NO single param!
/*
{{#allParams}}
* {{paramName}}
{{/allParams}}
*/
{{/hasSingleParam}}
{{^hasSingleParam}}

public record {{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.AbstractResource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.AbstractResource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}){}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,74 @@ public class {{classname}} {
this.apiClient = apiClient;
}

{{#operation}}
{{#operation}}{{#useSingleRequestParameter}}{{#hasParams}}{{^hasSingleParam}}
public class {{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request {
{{#allParams}}
private final {{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.AbstractResource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.AbstractResource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}};
{{/allParams}}

public {{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request({{#allParams}}{{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.AbstractResource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.AbstractResource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) {
{{#allParams}}
this.{{paramName}} = {{paramName}};
{{/allParams}}
}

{{#allParams}}
public {{#isFile}}{{#useAbstractionForFiles}}{{#collectionFormat}}java.util.Collection<org.springframework.core.io.AbstractResource>{{/collectionFormat}}{{^collectionFormat}}org.springframework.core.io.AbstractResource{{/collectionFormat}}{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{dataType}}}{{/useAbstractionForFiles}}{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}() {
return this.{{paramName}};
}
{{/allParams}}
}

/**
* {{summary}}
* {{notes}}
{{#responses}} * <p><b>{{code}}</b>{{#message}} - {{.}}{{/message}}
{{/responses}} * @param requestParameters The {{operationId}} request parameters as object
{{#returnType}} * @return {{.}}
{{/returnType}} * @throws WebClientResponseException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
public {{#returnType}}{{#vendorExtensions.x-webclient-blocking}}{{#vendorExtensions.x-webclient-return-except-list-of-string}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnBaseType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnBaseType}}}{{/isResponseFile}}>{{/vendorExtensions.x-webclient-return-except-list-of-string}}{{^vendorExtensions.x-webclient-return-except-list-of-string}}{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}}{{/vendorExtensions.x-webclient-return-except-list-of-string}}{{/vendorExtensions.x-webclient-blocking}}{{^vendorExtensions.x-webclient-blocking}}{{#vendorExtensions.x-webclient-return-except-list-of-string}}Flux<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnBaseType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnBaseType}}}{{/isResponseFile}}>{{/vendorExtensions.x-webclient-return-except-list-of-string}}{{^vendorExtensions.x-webclient-return-except-list-of-string}}Mono<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}}>{{/vendorExtensions.x-webclient-return-except-list-of-string}}{{/vendorExtensions.x-webclient-blocking}} {{/returnType}}{{^returnType}}{{#vendorExtensions.x-webclient-blocking}}void{{/vendorExtensions.x-webclient-blocking}}{{^vendorExtensions.x-webclient-blocking}}Mono<Void>{{/vendorExtensions.x-webclient-blocking}} {{/returnType}}{{operationId}}({{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request requestParameters) throws WebClientResponseException {
{{^returnType}}{{^vendorExtensions.x-webclient-blocking}}return {{/vendorExtensions.x-webclient-blocking}}{{/returnType}}{{#returnType}}return {{/returnType}}this.{{operationId}}({{#allParams}}requestParameters.{{paramName}}(){{^-last}}, {{/-last}}{{/allParams}});
}

/**
* {{summary}}
* {{notes}}
{{#responses}} * <p><b>{{code}}</b>{{#message}} - {{.}}{{/message}}
{{/responses}} * @param requestParameters The {{operationId}} request parameters as object
{{#returnType}} * @return ResponseEntity&lt;{{.}}&gt;
{{/returnType}} * @throws WebClientResponseException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
public {{#vendorExtensions.x-webclient-blocking}}{{#returnType}}{{#vendorExtensions.x-webclient-return-except-list-of-string}}ResponseEntity<List<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnBaseType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnBaseType}}}{{/isResponseFile}}>>{{/vendorExtensions.x-webclient-return-except-list-of-string}}{{^vendorExtensions.x-webclient-return-except-list-of-string}}ResponseEntity<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}}>{{/vendorExtensions.x-webclient-return-except-list-of-string}}{{/returnType}}{{^returnType}}ResponseEntity<Void>{{/returnType}} {{/vendorExtensions.x-webclient-blocking}}{{^vendorExtensions.x-webclient-blocking}}{{#returnType}}{{#vendorExtensions.x-webclient-return-except-list-of-string}}Mono<ResponseEntity<List<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnBaseType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnBaseType}}}{{/isResponseFile}}>>>{{/vendorExtensions.x-webclient-return-except-list-of-string}}{{^vendorExtensions.x-webclient-return-except-list-of-string}}Mono<ResponseEntity<{{#isResponseFile}}{{#useAbstractionForFiles}}org.springframework.core.io.Resource{{/useAbstractionForFiles}}{{^useAbstractionForFiles}}{{{returnType}}}{{/useAbstractionForFiles}}{{/isResponseFile}}{{^isResponseFile}}{{{returnType}}}{{/isResponseFile}}>>{{/vendorExtensions.x-webclient-return-except-list-of-string}}{{/returnType}}{{^returnType}}Mono<ResponseEntity<Void>>{{/returnType}} {{/vendorExtensions.x-webclient-blocking}}{{operationId}}WithHttpInfo({{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request requestParameters) throws WebClientResponseException {
return this.{{operationId}}WithHttpInfo({{#allParams}}requestParameters.{{paramName}}(){{^-last}}, {{/-last}}{{/allParams}});
}

/**
* {{summary}}
* {{notes}}
{{#responses}} * <p><b>{{code}}</b>{{#message}} - {{.}}{{/message}}
{{/responses}} * @param requestParameters The {{operationId}} request parameters as object
* @return ResponseSpec
* @throws WebClientResponseException if an error occurs while attempting to invoke the API
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
public ResponseSpec {{operationId}}WithResponseSpec({{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request requestParameters) throws WebClientResponseException {
return this.{{operationId}}WithResponseSpec({{#allParams}}requestParameters.{{paramName}}(){{^-last}}, {{/-last}}{{/allParams}});
}

{{/hasSingleParam}}{{/hasParams}}{{/useSingleRequestParameter}}
/**
* {{summary}}
* {{notes}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3210,6 +3210,35 @@ public void testDuplicatedOperationId() {
);
}

@Test public void testWebClientWithUseSingleRequestParameter_issue_19407() {
final Path output = newTempFolder();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("java")
.setLibrary(JavaClientCodegen.WEBCLIENT)
.setAdditionalProperties(Map.of(
CodegenConstants.API_PACKAGE, "xyz.abcdef.api",
CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, true
))
.setInputSpec("src/test/resources/3_1/java/petstore.yaml")
.setOutputDir(output.toString().replace("\\", "/"));

new DefaultGenerator().opts(configurator.toClientOptInput()).generate();

TestUtils.assertFileContains(
output.resolve("src/main/java/xyz/abcdef/api/PetApi.java"),
"public class DeletePetRequest {",
"DeletePetRequest(Long petId, String apiKey)",
"Long petId()",
"String apiKey()",
"public Mono<Void> deletePet(DeletePetRequest requestParameters) throws WebClientResponseException {",
"public Mono<ResponseEntity<Void>> deletePetWithHttpInfo(DeletePetRequest requestParameters) throws WebClientResponseException {",
"public ResponseSpec deletePetWithResponseSpec(DeletePetRequest requestParameters) throws WebClientResponseException {",
"public Mono<Void> deletePet(Long petId, String apiKey) throws WebClientResponseException {",
"public Mono<ResponseEntity<Void>> deletePetWithHttpInfo(Long petId, String apiKey) throws WebClientResponseException {",
"public ResponseSpec deletePetWithResponseSpec(Long petId, String apiKey) throws WebClientResponseException {"
);
}

@Test
public void testGenerateParameterId() {
final Path output = newTempFolder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public void setApiClient(ApiClient apiClient) {
this.apiClient = apiClient;
}


/**
*
* Response file abstraction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ public void setApiClient(ApiClient apiClient) {
this.apiClient = apiClient;
}

// It has a single param!
/*
* client
*/
/**
* To test special tags
* To test special tags and operation ID starting with number
Expand Down
Loading

0 comments on commit 07d19ba

Please sign in to comment.