diff --git a/docs/generators/java-microprofile.md b/docs/generators/java-microprofile.md index c9847543aea..a431d02662c 100644 --- a/docs/generators/java-microprofile.md +++ b/docs/generators/java-microprofile.md @@ -101,7 +101,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, Spring WebClient support this option. Setting this property to "static" does the same as "true", but also makes the generated arguments class static with single parameter instantiation.| |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 native, jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to "static" does the same as "true", but also makes the generated arguments class static with single parameter instantiation.| |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| diff --git a/docs/generators/java.md b/docs/generators/java.md index 528baf68b77..be1003296dc 100644 --- a/docs/generators/java.md +++ b/docs/generators/java.md @@ -101,7 +101,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, Spring WebClient support this option. Setting this property to "static" does the same as "true", but also makes the generated arguments class static with single parameter instantiation.| |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 native, jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to "static" does the same as "true", but also makes the generated arguments class static with single parameter instantiation.| |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| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java index ae9c6d8c2ba..735f27aacd6 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java @@ -239,7 +239,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen 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.newString(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. Setting this property to \"static\" does the same as \"true\", but also makes the generated arguments class static with single parameter instantiation.").defaultValue("false")); + cliOptions.add(CliOption.newString(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 native, jersey2, jersey3, okhttp-gson, microprofile, Spring RestClient, Spring WebClient support this option. Setting this property to \"static\" does the same as \"true\", but also makes the generated arguments class static with single parameter instantiation.").defaultValue("false")); 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, restclient and webclient, 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.")); @@ -800,7 +800,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) { super.postProcessOperationsWithModels(objs, allModels); - if (this.getSingleRequestParameter() && (isLibrary(JERSEY2) || isLibrary(JERSEY3) || isLibrary(OKHTTP_GSON))) { + if (this.getSingleRequestParameter() && (isLibrary(JERSEY2) || isLibrary(JERSEY3) || isLibrary(OKHTTP_GSON) || isLibrary(NATIVE))) { // loop through operations to set x-group-parameters extension to true if useSingleRequestParameter option is enabled OperationMap operations = objs.getOperations(); if (operations != null) { diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/native/api.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/native/api.mustache index a136709bade..401bcb8845f 100644 --- a/modules/openapi-generator/src/main/resources/Java/libraries/native/api.mustache +++ b/modules/openapi-generator/src/main/resources/Java/libraries/native/api.mustache @@ -106,7 +106,7 @@ public class {{classname}} { /** * {{summary}} * {{notes}} - * @param apiRequest {@link API{{operationId}}Request} + * @param apiRequest {@link API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request} {{#returnType}} * @return {{#asyncNative}}CompletableFuture<{{/asyncNative}}{{returnType}}{{#asyncNative}}>{{/asyncNative}} {{/returnType}} @@ -127,7 +127,7 @@ public class {{classname}} { {{#isDeprecated}} @Deprecated {{/isDeprecated}} - public {{#returnType}}{{#asyncNative}}CompletableFuture<{{{returnType}}}>{{/asyncNative}}{{^asyncNative}}{{{returnType}}}{{/asyncNative}}{{/returnType}}{{^returnType}}{{#asyncNative}}CompletableFuture{{/asyncNative}}{{^asyncNative}}void{{/asyncNative}}{{/returnType}} {{operationId}}(API{{operationId}}Request apiRequest) throws ApiException { + public {{#returnType}}{{#asyncNative}}CompletableFuture<{{{returnType}}}>{{/asyncNative}}{{^asyncNative}}{{{returnType}}}{{/asyncNative}}{{/returnType}}{{^returnType}}{{#asyncNative}}CompletableFuture{{/asyncNative}}{{^asyncNative}}void{{/asyncNative}}{{/returnType}} {{operationId}}(API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request apiRequest) throws ApiException { {{#allParams}} {{>nullable_var_annotations}} {{{dataType}}} {{paramName}} = apiRequest.{{paramName}}(); @@ -138,7 +138,7 @@ public class {{classname}} { /** * {{summary}} * {{notes}} - * @param apiRequest {@link API{{operationId}}Request} + * @param apiRequest {@link API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request} * @return {{#asyncNative}}CompletableFuture<{{/asyncNative}}ApiResponse<{{returnType}}{{^returnType}}Void{{/returnType}}>{{#asyncNative}}>{{/asyncNative}} * @throws ApiException if fails to make API call {{#isDeprecated}} @@ -152,7 +152,7 @@ public class {{classname}} { {{#isDeprecated}} @Deprecated {{/isDeprecated}} - public {{#asyncNative}}CompletableFuture<{{/asyncNative}}ApiResponse<{{{returnType}}}{{^returnType}}Void{{/returnType}}>{{#asyncNative}}>{{/asyncNative}} {{operationId}}WithHttpInfo(API{{operationId}}Request apiRequest) throws ApiException { + public {{#asyncNative}}CompletableFuture<{{/asyncNative}}ApiResponse<{{{returnType}}}{{^returnType}}Void{{/returnType}}>{{#asyncNative}}>{{/asyncNative}} {{operationId}}WithHttpInfo(API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request apiRequest) throws ApiException { {{#allParams}} {{{dataType}}} {{paramName}} = apiRequest.{{paramName}}(); {{/allParams}} @@ -574,7 +574,7 @@ public class {{classname}} { {{#vendorExtensions.x-group-parameters}} {{#hasParams}} - public static final class API{{operationId}}Request { + public static final class API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request { {{#requiredParams}} {{>nullable_var_annotations}} private {{{dataType}}} {{paramName}}; // {{description}} (required) @@ -584,7 +584,7 @@ public class {{classname}} { private {{{dataType}}} {{paramName}}; // {{description}} (optional{{^isContainer}}{{#defaultValue}}, default to {{.}}{{/defaultValue}}{{/isContainer}}) {{/optionalParams}} - private API{{operationId}}Request(Builder builder) { + private API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request(Builder builder) { {{#requiredParams}} this.{{paramName}} = builder.{{paramName}}; {{/requiredParams}} @@ -616,8 +616,8 @@ public class {{classname}} { return this; } {{/allParams}} - public API{{operationId}}Request build() { - return new API{{operationId}}Request(this); + public API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request build() { + return new API{{#lambda.titlecase}}{{operationId}}{{/lambda.titlecase}}Request(this); } } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index 63539efc718..261812787f1 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -3237,6 +3237,7 @@ public class JavaClientCodegenTest { "String apiKey()", "DeletePetRequest apiKey(@jakarta.annotation.Nullable String apiKey) {", "public void deletePet(DeletePetRequest requestParameters) throws RestClientResponseException {", + "Pet getPetById(@jakarta.annotation.Nonnull Long petId) throws RestClientResponseException", "public ResponseEntity deletePetWithHttpInfo(DeletePetRequest requestParameters) throws RestClientResponseException {", "public ResponseSpec deletePetWithResponseSpec(DeletePetRequest requestParameters) throws RestClientResponseException {", "public void deletePet(@jakarta.annotation.Nonnull Long petId, @jakarta.annotation.Nullable String apiKey) throws RestClientResponseException {", @@ -3665,4 +3666,37 @@ public class JavaClientCodegenTest { assertTrue(defaultFields.get("testNullableEmptyReference").getVariable(0).getInitializer().get().isObjectCreationExpr()); assertTrue(defaultFields.get("testNullableComplexReference").getVariable(0).getInitializer().get().isMethodCallExpr()); } + + @Test + public void testNativeClientWithUseSingleRequestParameter() { + final Path output = newTempFolder(); + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("java") + .setLibrary(NATIVE) + .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 static final class APIDeletePetRequest {", + "private APIDeletePetRequest(Builder builder) {", + "public Builder petId(@javax.annotation.Nonnull Long petId) {", + "public Builder apiKey(@javax.annotation.Nullable String apiKey) {", + "Long petId()", + "String apiKey()", + "public void deletePet(APIDeletePetRequest apiRequest) throws ApiException {", + "Pet getPetById(@javax.annotation.Nonnull Long petId) throws ApiException", + "public ApiResponse deletePetWithHttpInfo(APIDeletePetRequest apiRequest) throws ApiException {", + "public void deletePet(@javax.annotation.Nonnull Long petId, @javax.annotation.Nullable String apiKey) throws ApiException {", + "public ApiResponse deletePetWithHttpInfo(@javax.annotation.Nonnull Long petId, @javax.annotation.Nullable String apiKey) throws ApiException {" + ); + TestUtils.assertFileNotContains(output.resolve("src/main/java/xyz/abcdef/api/PetApi.java"), + "public record DeletePetRequest(Long petId, String apiKey){}"); + } } \ No newline at end of file diff --git a/samples/client/petstore/java/native-async/src/main/java/org/openapitools/client/api/FakeApi.java b/samples/client/petstore/java/native-async/src/main/java/org/openapitools/client/api/FakeApi.java index de019af8382..d11db59aa60 100644 --- a/samples/client/petstore/java/native-async/src/main/java/org/openapitools/client/api/FakeApi.java +++ b/samples/client/petstore/java/native-async/src/main/java/org/openapitools/client/api/FakeApi.java @@ -1501,11 +1501,11 @@ public class FakeApi { /** * Fake endpoint to test group parameters (optional) * Fake endpoint to test group parameters (optional) - * @param apiRequest {@link APItestGroupParametersRequest} + * @param apiRequest {@link APITestGroupParametersRequest} * @return CompletableFuture<Void> * @throws ApiException if fails to make API call */ - public CompletableFuture testGroupParameters(APItestGroupParametersRequest apiRequest) throws ApiException { + public CompletableFuture testGroupParameters(APITestGroupParametersRequest apiRequest) throws ApiException { @javax.annotation.Nonnull Integer requiredStringGroup = apiRequest.requiredStringGroup(); @javax.annotation.Nonnull @@ -1524,11 +1524,11 @@ public class FakeApi { /** * Fake endpoint to test group parameters (optional) * Fake endpoint to test group parameters (optional) - * @param apiRequest {@link APItestGroupParametersRequest} + * @param apiRequest {@link APITestGroupParametersRequest} * @return CompletableFuture<ApiResponse<Void>> * @throws ApiException if fails to make API call */ - public CompletableFuture> testGroupParametersWithHttpInfo(APItestGroupParametersRequest apiRequest) throws ApiException { + public CompletableFuture> testGroupParametersWithHttpInfo(APITestGroupParametersRequest apiRequest) throws ApiException { Integer requiredStringGroup = apiRequest.requiredStringGroup(); Boolean requiredBooleanGroup = apiRequest.requiredBooleanGroup(); Long requiredInt64Group = apiRequest.requiredInt64Group(); @@ -1662,7 +1662,7 @@ public class FakeApi { } - public static final class APItestGroupParametersRequest { + public static final class APITestGroupParametersRequest { @javax.annotation.Nonnull private Integer requiredStringGroup; // Required String in group parameters (required) @javax.annotation.Nonnull @@ -1676,7 +1676,7 @@ public class FakeApi { @javax.annotation.Nullable private Long int64Group; // Integer in group parameters (optional) - private APItestGroupParametersRequest(Builder builder) { + private APITestGroupParametersRequest(Builder builder) { this.requiredStringGroup = builder.requiredStringGroup; this.requiredBooleanGroup = builder.requiredBooleanGroup; this.requiredInt64Group = builder.requiredInt64Group; @@ -1744,8 +1744,8 @@ public class FakeApi { this.int64Group = int64Group; return this; } - public APItestGroupParametersRequest build() { - return new APItestGroupParametersRequest(this); + public APITestGroupParametersRequest build() { + return new APITestGroupParametersRequest(this); } } } diff --git a/samples/client/petstore/java/native-async/src/test/java/org/openapitools/client/api/FakeApiTest.java b/samples/client/petstore/java/native-async/src/test/java/org/openapitools/client/api/FakeApiTest.java index edc826fba0e..e45f36d0fa5 100644 --- a/samples/client/petstore/java/native-async/src/test/java/org/openapitools/client/api/FakeApiTest.java +++ b/samples/client/petstore/java/native-async/src/test/java/org/openapitools/client/api/FakeApiTest.java @@ -318,7 +318,7 @@ public class FakeApiTest { Boolean booleanGroup = null; Long int64Group = null; - FakeApi.APItestGroupParametersRequest request = FakeApi.APItestGroupParametersRequest.newBuilder() + FakeApi.APITestGroupParametersRequest request = FakeApi.APITestGroupParametersRequest.newBuilder() .requiredStringGroup(requiredStringGroup) .requiredBooleanGroup(requiredBooleanGroup) .requiredInt64Group(requiredInt64Group) diff --git a/samples/client/petstore/java/native/src/main/java/org/openapitools/client/api/FakeApi.java b/samples/client/petstore/java/native/src/main/java/org/openapitools/client/api/FakeApi.java index b0938e3a12c..36fecc00484 100644 --- a/samples/client/petstore/java/native/src/main/java/org/openapitools/client/api/FakeApi.java +++ b/samples/client/petstore/java/native/src/main/java/org/openapitools/client/api/FakeApi.java @@ -1395,10 +1395,10 @@ public class FakeApi { /** * Fake endpoint to test group parameters (optional) * Fake endpoint to test group parameters (optional) - * @param apiRequest {@link APItestGroupParametersRequest} + * @param apiRequest {@link APITestGroupParametersRequest} * @throws ApiException if fails to make API call */ - public void testGroupParameters(APItestGroupParametersRequest apiRequest) throws ApiException { + public void testGroupParameters(APITestGroupParametersRequest apiRequest) throws ApiException { @javax.annotation.Nonnull Integer requiredStringGroup = apiRequest.requiredStringGroup(); @javax.annotation.Nonnull @@ -1417,11 +1417,11 @@ public class FakeApi { /** * Fake endpoint to test group parameters (optional) * Fake endpoint to test group parameters (optional) - * @param apiRequest {@link APItestGroupParametersRequest} + * @param apiRequest {@link APITestGroupParametersRequest} * @return ApiResponse<Void> * @throws ApiException if fails to make API call */ - public ApiResponse testGroupParametersWithHttpInfo(APItestGroupParametersRequest apiRequest) throws ApiException { + public ApiResponse testGroupParametersWithHttpInfo(APITestGroupParametersRequest apiRequest) throws ApiException { Integer requiredStringGroup = apiRequest.requiredStringGroup(); Boolean requiredBooleanGroup = apiRequest.requiredBooleanGroup(); Long requiredInt64Group = apiRequest.requiredInt64Group(); @@ -1552,7 +1552,7 @@ public class FakeApi { } - public static final class APItestGroupParametersRequest { + public static final class APITestGroupParametersRequest { @javax.annotation.Nonnull private Integer requiredStringGroup; // Required String in group parameters (required) @javax.annotation.Nonnull @@ -1566,7 +1566,7 @@ public class FakeApi { @javax.annotation.Nullable private Long int64Group; // Integer in group parameters (optional) - private APItestGroupParametersRequest(Builder builder) { + private APITestGroupParametersRequest(Builder builder) { this.requiredStringGroup = builder.requiredStringGroup; this.requiredBooleanGroup = builder.requiredBooleanGroup; this.requiredInt64Group = builder.requiredInt64Group; @@ -1634,8 +1634,8 @@ public class FakeApi { this.int64Group = int64Group; return this; } - public APItestGroupParametersRequest build() { - return new APItestGroupParametersRequest(this); + public APITestGroupParametersRequest build() { + return new APITestGroupParametersRequest(this); } } } diff --git a/samples/client/petstore/java/native/src/test/java/org/openapitools/client/api/FakeApiTest.java b/samples/client/petstore/java/native/src/test/java/org/openapitools/client/api/FakeApiTest.java index b67953dddcd..7f7046d94f4 100644 --- a/samples/client/petstore/java/native/src/test/java/org/openapitools/client/api/FakeApiTest.java +++ b/samples/client/petstore/java/native/src/test/java/org/openapitools/client/api/FakeApiTest.java @@ -317,7 +317,7 @@ public class FakeApiTest { Boolean booleanGroup = null; Long int64Group = null; - FakeApi.APItestGroupParametersRequest request = FakeApi.APItestGroupParametersRequest.newBuilder() + FakeApi.APITestGroupParametersRequest request = FakeApi.APITestGroupParametersRequest.newBuilder() .requiredStringGroup(requiredStringGroup) .requiredBooleanGroup(requiredBooleanGroup) .requiredInt64Group(requiredInt64Group)