diff --git a/bin/configs/spring-cloud-petstore-feign-without-url-param.yaml b/bin/configs/spring-cloud-petstore-feign-without-url-param.yaml
new file mode 100644
index 00000000000..9b86ed155ed
--- /dev/null
+++ b/bin/configs/spring-cloud-petstore-feign-without-url-param.yaml
@@ -0,0 +1,10 @@
+generatorName: spring
+outputDir: samples/client/petstore/spring-cloud-feign-without-url
+library: spring-cloud
+inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
+templateDir: modules/openapi-generator/src/main/resources/JavaSpring
+additionalProperties:
+ documentationProvider: springfox
+ artifactId: petstore-spring-cloud
+ hideGenerationTimestamp: "true"
+ useFeignClientUrl: "false"
diff --git a/docs/generators/java-camel.md b/docs/generators/java-camel.md
index 9e919ce2be8..69d3472e489 100644
--- a/docs/generators/java-camel.md
+++ b/docs/generators/java-camel.md
@@ -89,6 +89,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|server title name or client service name| |OpenAPI Spring|
|unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false|
|useBeanValidation|Use BeanValidation API annotations| |true|
+|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useOptional|Use Optional container for optional parameters| |false|
|useSpringController|Annotate the generated API as a Spring Controller| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
diff --git a/docs/generators/spring.md b/docs/generators/spring.md
index 1bf1f24edb7..d53eec50882 100644
--- a/docs/generators/spring.md
+++ b/docs/generators/spring.md
@@ -82,6 +82,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|server title name or client service name| |OpenAPI Spring|
|unhandledException|Declare operation methods to throw a generic exception and allow unhandled exceptions (useful for Spring `@ControllerAdvice` directives).| |false|
|useBeanValidation|Use BeanValidation API annotations| |true|
+|useFeignClientUrl|Whether to generate Feign client with url parameter.| |true|
|useOptional|Use Optional container for optional parameters| |false|
|useSpringController|Annotate the generated API as a Spring Controller| |false|
|useSwaggerUI|Open the OpenApi specification in swagger-ui. Will also import and configure needed dependencies| |true|
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java
index 4067c83c76b..26a5311f86a 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java
@@ -82,6 +82,7 @@ public class SpringCodegen extends AbstractJavaCodegen
public static final String CONFIG_PACKAGE = "configPackage";
public static final String BASE_PACKAGE = "basePackage";
public static final String INTERFACE_ONLY = "interfaceOnly";
+ public static final String USE_FEIGN_CLIENT_URL = "useFeignClientUrl";
public static final String DELEGATE_PATTERN = "delegatePattern";
public static final String SINGLE_CONTENT_TYPES = "singleContentTypes";
public static final String VIRTUAL_SERVICE = "virtualService";
@@ -106,6 +107,7 @@ public class SpringCodegen extends AbstractJavaCodegen
protected String configPackage = "org.openapitools.configuration";
protected String basePackage = "org.openapitools";
protected boolean interfaceOnly = false;
+ protected boolean useFeignClientUrl = true;
protected boolean delegatePattern = false;
protected boolean delegateMethod = false;
protected boolean singleContentTypes = false;
@@ -166,6 +168,8 @@ public class SpringCodegen extends AbstractJavaCodegen
.defaultValue(this.getBasePackage()));
cliOptions.add(CliOption.newBoolean(INTERFACE_ONLY,
"Whether to generate only API interface stubs without the server files.", interfaceOnly));
+ cliOptions.add(CliOption.newBoolean(USE_FEIGN_CLIENT_URL,
+ "Whether to generate Feign client with url parameter.", useFeignClientUrl));
cliOptions.add(CliOption.newBoolean(DELEGATE_PATTERN,
"Whether to generate the server files using the delegate pattern", delegatePattern));
cliOptions.add(CliOption.newBoolean(SINGLE_CONTENT_TYPES,
@@ -325,6 +329,11 @@ public class SpringCodegen extends AbstractJavaCodegen
this.setInterfaceOnly(Boolean.parseBoolean(additionalProperties.get(INTERFACE_ONLY).toString()));
}
+ if (additionalProperties.containsKey(USE_FEIGN_CLIENT_URL)) {
+ this.setUseFeignClientUrl(Boolean.parseBoolean(additionalProperties.get(USE_FEIGN_CLIENT_URL).toString()));
+ }
+ writePropertyBack(USE_FEIGN_CLIENT_URL, useFeignClientUrl);
+
if (additionalProperties.containsKey(DELEGATE_PATTERN)) {
this.setDelegatePattern(Boolean.parseBoolean(additionalProperties.get(DELEGATE_PATTERN).toString()));
}
@@ -790,6 +799,10 @@ public class SpringCodegen extends AbstractJavaCodegen
this.interfaceOnly = interfaceOnly;
}
+ public void setUseFeignClientUrl(boolean useFeignClientUrl) {
+ this.useFeignClientUrl = useFeignClientUrl;
+ }
+
public void setDelegatePattern(boolean delegatePattern) {
this.delegatePattern = delegatePattern;
}
diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/apiClient.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/apiClient.mustache
index f00a6c3b6f7..adc5145d080 100644
--- a/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/apiClient.mustache
+++ b/modules/openapi-generator/src/main/resources/JavaSpring/libraries/spring-cloud/apiClient.mustache
@@ -3,8 +3,6 @@ package {{package}};
import org.springframework.cloud.openfeign.FeignClient;
import {{configPackage}}.ClientConfiguration;
-{{=<% %>=}}
-@FeignClient(name="${<%classVarName%>.name:<%classVarName%>}", url="${<%classVarName%>.url:<%basePath%>}", configuration = ClientConfiguration.class)
-<%={{ }}=%>
+@FeignClient(name="${{openbrace}}{{classVarName}}.name:{{classVarName}}{{closebrace}}", {{#useFeignClientUrl}}url="${{openbrace}}{{classVarName}}.url:{{basePath}}{{closebrace}}", {{/useFeignClientUrl}}configuration = ClientConfiguration.class)
public interface {{classname}}Client extends {{classname}} {
}
diff --git a/samples/client/petstore/spring-cloud-feign-without-url/.openapi-generator-ignore b/samples/client/petstore/spring-cloud-feign-without-url/.openapi-generator-ignore
new file mode 100644
index 00000000000..7484ee590a3
--- /dev/null
+++ b/samples/client/petstore/spring-cloud-feign-without-url/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/client/petstore/spring-cloud-feign-without-url/.openapi-generator/FILES b/samples/client/petstore/spring-cloud-feign-without-url/.openapi-generator/FILES
new file mode 100644
index 00000000000..3510d2b2d27
--- /dev/null
+++ b/samples/client/petstore/spring-cloud-feign-without-url/.openapi-generator/FILES
@@ -0,0 +1,16 @@
+README.md
+pom.xml
+src/main/java/org/openapitools/api/PetApi.java
+src/main/java/org/openapitools/api/PetApiClient.java
+src/main/java/org/openapitools/api/StoreApi.java
+src/main/java/org/openapitools/api/StoreApiClient.java
+src/main/java/org/openapitools/api/UserApi.java
+src/main/java/org/openapitools/api/UserApiClient.java
+src/main/java/org/openapitools/configuration/ApiKeyRequestInterceptor.java
+src/main/java/org/openapitools/configuration/ClientConfiguration.java
+src/main/java/org/openapitools/model/Category.java
+src/main/java/org/openapitools/model/ModelApiResponse.java
+src/main/java/org/openapitools/model/Order.java
+src/main/java/org/openapitools/model/Pet.java
+src/main/java/org/openapitools/model/Tag.java
+src/main/java/org/openapitools/model/User.java
diff --git a/samples/client/petstore/spring-cloud-feign-without-url/.openapi-generator/VERSION b/samples/client/petstore/spring-cloud-feign-without-url/.openapi-generator/VERSION
new file mode 100644
index 00000000000..5f68295fc19
--- /dev/null
+++ b/samples/client/petstore/spring-cloud-feign-without-url/.openapi-generator/VERSION
@@ -0,0 +1 @@
+6.0.0-SNAPSHOT
\ No newline at end of file
diff --git a/samples/client/petstore/spring-cloud-feign-without-url/README.md b/samples/client/petstore/spring-cloud-feign-without-url/README.md
new file mode 100644
index 00000000000..f176b79c8ae
--- /dev/null
+++ b/samples/client/petstore/spring-cloud-feign-without-url/README.md
@@ -0,0 +1,53 @@
+# petstore-spring-cloud
+
+## Requirements
+
+Building the API client library requires [Maven](https://maven.apache.org/) to be installed.
+
+## Installation
+
+To install the API client library to your local Maven repository, simply execute:
+
+```shell
+mvn install
+```
+
+To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
+
+```shell
+mvn deploy
+```
+
+Refer to the [official documentation](https://maven.apache.org/plugins/maven-deploy-plugin/usage.html) for more information.
+
+### Maven users
+
+Add this dependency to your project's POM:
+
+```xml
+
+ org.openapitools
+ petstore-spring-cloud
+ 1.0.0
+ compile
+
+```
+
+### Gradle users
+
+Add this dependency to your project's build file:
+
+```groovy
+compile "org.openapitools:petstore-spring-cloud:1.0.0"
+```
+
+### Others
+
+At first generate the JAR by executing:
+
+mvn package
+
+Then manually install the following JARs:
+
+* target/petstore-spring-cloud-1.0.0.jar
+* target/lib/*.jar
diff --git a/samples/client/petstore/spring-cloud-feign-without-url/pom.xml b/samples/client/petstore/spring-cloud-feign-without-url/pom.xml
new file mode 100644
index 00000000000..5b7846a57eb
--- /dev/null
+++ b/samples/client/petstore/spring-cloud-feign-without-url/pom.xml
@@ -0,0 +1,82 @@
+
+ 4.0.0
+ org.openapitools
+ petstore-spring-cloud
+ jar
+ petstore-spring-cloud
+ 1.0.0
+
+ 1.8
+ ${java.version}
+ ${java.version}
+ UTF-8
+ 2.9.2
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.6
+
+
+
+ src/main/java
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-parent
+ 2021.0.1
+ pom
+ import
+
+
+
+
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${springfox.version}
+
+
+
+ com.google.code.findbugs
+ jsr305
+ 3.0.2
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+
+
+ org.springframework.cloud
+ spring-cloud-starter-oauth2
+ 2.2.5.RELEASE
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+ org.openapitools
+ jackson-databind-nullable
+ 0.2.2
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.data
+ spring-data-commons
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
diff --git a/samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/PetApi.java b/samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/PetApi.java
new file mode 100644
index 00000000000..64a724c1680
--- /dev/null
+++ b/samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/PetApi.java
@@ -0,0 +1,318 @@
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (6.0.0-SNAPSHOT).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+package org.openapitools.api;
+
+import org.openapitools.model.ModelApiResponse;
+import org.openapitools.model.Pet;
+import io.swagger.annotations.*;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import javax.annotation.Generated;
+
+@Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
+@Validated
+@Api(value = "Pet", description = "Everything about your Pets")
+public interface PetApi {
+
+ /**
+ * POST /pet : Add a new pet to the store
+ *
+ *
+ * @param pet Pet object that needs to be added to the store (required)
+ * @return successful operation (status code 200)
+ * or Invalid input (status code 405)
+ */
+ @ApiOperation(
+ tags = { "pet" },
+ value = "Add a new pet to the store",
+ nickname = "addPet",
+ notes = "",
+ response = Pet.class,
+ authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }
+ )
+ @ApiResponses({
+ @ApiResponse(code = 200, message = "successful operation", response = Pet.class),
+ @ApiResponse(code = 405, message = "Invalid input")
+ })
+ @RequestMapping(
+ method = RequestMethod.POST,
+ value = "/pet",
+ produces = "application/json",
+ consumes = "application/json"
+ )
+ ResponseEntity addPet(
+ @ApiParam(value = "Pet object that needs to be added to the store", required = true) @Valid @RequestBody Pet pet
+ );
+
+
+ /**
+ * DELETE /pet/{petId} : Deletes a pet
+ *
+ *
+ * @param petId Pet id to delete (required)
+ * @param apiKey (optional)
+ * @return Invalid pet value (status code 400)
+ */
+ @ApiOperation(
+ tags = { "pet" },
+ value = "Deletes a pet",
+ nickname = "deletePet",
+ notes = "",
+ authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }
+ )
+ @ApiResponses({
+ @ApiResponse(code = 400, message = "Invalid pet value")
+ })
+ @RequestMapping(
+ method = RequestMethod.DELETE,
+ value = "/pet/{petId}"
+ )
+ ResponseEntity deletePet(
+ @ApiParam(value = "Pet id to delete", required = true) @PathVariable("petId") Long petId,
+ @ApiParam(value = "") @RequestHeader(value = "api_key", required = false) String apiKey
+ );
+
+
+ /**
+ * GET /pet/findByStatus : Finds Pets by status
+ * Multiple status values can be provided with comma separated strings
+ *
+ * @param status Status values that need to be considered for filter (required)
+ * @return successful operation (status code 200)
+ * or Invalid status value (status code 400)
+ */
+ @ApiOperation(
+ tags = { "pet" },
+ value = "Finds Pets by status",
+ nickname = "findPetsByStatus",
+ notes = "Multiple status values can be provided with comma separated strings",
+ response = Pet.class,
+ responseContainer = "List",
+ authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }
+ )
+ @ApiResponses({
+ @ApiResponse(code = 200, message = "successful operation", response = Pet.class, responseContainer = "List"),
+ @ApiResponse(code = 400, message = "Invalid status value")
+ })
+ @RequestMapping(
+ method = RequestMethod.GET,
+ value = "/pet/findByStatus",
+ produces = "application/json"
+ )
+ ResponseEntity> findPetsByStatus(
+ @NotNull @ApiParam(value = "Status values that need to be considered for filter", required = true, allowableValues = "available, pending, sold") @Valid @RequestParam(value = "status", required = true) List status
+ );
+
+
+ /**
+ * GET /pet/findByTags : Finds Pets by tags
+ * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+ *
+ * @param tags Tags to filter by (required)
+ * @return successful operation (status code 200)
+ * or Invalid tag value (status code 400)
+ * @deprecated
+ */
+ @ApiOperation(
+ tags = { "pet" },
+ value = "Finds Pets by tags",
+ nickname = "findPetsByTags",
+ notes = "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
+ response = Pet.class,
+ responseContainer = "List",
+ authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }
+ )
+ @ApiResponses({
+ @ApiResponse(code = 200, message = "successful operation", response = Pet.class, responseContainer = "List"),
+ @ApiResponse(code = 400, message = "Invalid tag value")
+ })
+ @RequestMapping(
+ method = RequestMethod.GET,
+ value = "/pet/findByTags",
+ produces = "application/json"
+ )
+ ResponseEntity> findPetsByTags(
+ @NotNull @ApiParam(value = "Tags to filter by", required = true) @Valid @RequestParam(value = "tags", required = true) List tags
+ );
+
+
+ /**
+ * GET /pet/{petId} : Find pet by ID
+ * Returns a single pet
+ *
+ * @param petId ID of pet to return (required)
+ * @return successful operation (status code 200)
+ * or Invalid ID supplied (status code 400)
+ * or Pet not found (status code 404)
+ */
+ @ApiOperation(
+ tags = { "pet" },
+ value = "Find pet by ID",
+ nickname = "getPetById",
+ notes = "Returns a single pet",
+ response = Pet.class,
+ authorizations = {
+ @Authorization(value = "api_key")
+ }
+ )
+ @ApiResponses({
+ @ApiResponse(code = 200, message = "successful operation", response = Pet.class),
+ @ApiResponse(code = 400, message = "Invalid ID supplied"),
+ @ApiResponse(code = 404, message = "Pet not found")
+ })
+ @RequestMapping(
+ method = RequestMethod.GET,
+ value = "/pet/{petId}",
+ produces = "application/json"
+ )
+ ResponseEntity getPetById(
+ @ApiParam(value = "ID of pet to return", required = true) @PathVariable("petId") Long petId
+ );
+
+
+ /**
+ * PUT /pet : Update an existing pet
+ *
+ *
+ * @param pet Pet object that needs to be added to the store (required)
+ * @return successful operation (status code 200)
+ * or Invalid ID supplied (status code 400)
+ * or Pet not found (status code 404)
+ * or Validation exception (status code 405)
+ */
+ @ApiOperation(
+ tags = { "pet" },
+ value = "Update an existing pet",
+ nickname = "updatePet",
+ notes = "",
+ response = Pet.class,
+ authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }
+ )
+ @ApiResponses({
+ @ApiResponse(code = 200, message = "successful operation", response = Pet.class),
+ @ApiResponse(code = 400, message = "Invalid ID supplied"),
+ @ApiResponse(code = 404, message = "Pet not found"),
+ @ApiResponse(code = 405, message = "Validation exception")
+ })
+ @RequestMapping(
+ method = RequestMethod.PUT,
+ value = "/pet",
+ produces = "application/json",
+ consumes = "application/json"
+ )
+ ResponseEntity updatePet(
+ @ApiParam(value = "Pet object that needs to be added to the store", required = true) @Valid @RequestBody Pet pet
+ );
+
+
+ /**
+ * POST /pet/{petId} : Updates a pet in the store with form data
+ *
+ *
+ * @param petId ID of pet that needs to be updated (required)
+ * @param name Updated name of the pet (optional)
+ * @param status Updated status of the pet (optional)
+ * @return Invalid input (status code 405)
+ */
+ @ApiOperation(
+ tags = { "pet" },
+ value = "Updates a pet in the store with form data",
+ nickname = "updatePetWithForm",
+ notes = "",
+ authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }
+ )
+ @ApiResponses({
+ @ApiResponse(code = 405, message = "Invalid input")
+ })
+ @RequestMapping(
+ method = RequestMethod.POST,
+ value = "/pet/{petId}",
+ consumes = "application/x-www-form-urlencoded"
+ )
+ ResponseEntity updatePetWithForm(
+ @ApiParam(value = "ID of pet that needs to be updated", required = true) @PathVariable("petId") Long petId,
+ @ApiParam(value = "Updated name of the pet") @Valid @RequestParam(value = "name", required = false) String name,
+ @ApiParam(value = "Updated status of the pet") @Valid @RequestParam(value = "status", required = false) String status
+ );
+
+
+ /**
+ * POST /pet/{petId}/uploadImage : uploads an image
+ *
+ *
+ * @param petId ID of pet to update (required)
+ * @param additionalMetadata Additional data to pass to server (optional)
+ * @param file file to upload (optional)
+ * @return successful operation (status code 200)
+ */
+ @ApiOperation(
+ tags = { "pet" },
+ value = "uploads an image",
+ nickname = "uploadFile",
+ notes = "",
+ response = ModelApiResponse.class,
+ authorizations = {
+ @Authorization(value = "petstore_auth", scopes = {
+ @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
+ @AuthorizationScope(scope = "read:pets", description = "read your pets")
+ })
+ }
+ )
+ @ApiResponses({
+ @ApiResponse(code = 200, message = "successful operation", response = ModelApiResponse.class)
+ })
+ @RequestMapping(
+ method = RequestMethod.POST,
+ value = "/pet/{petId}/uploadImage",
+ produces = "application/json",
+ consumes = "multipart/form-data"
+ )
+ ResponseEntity uploadFile(
+ @ApiParam(value = "ID of pet to update", required = true) @PathVariable("petId") Long petId,
+ @ApiParam(value = "Additional data to pass to server") @Valid @RequestParam(value = "additionalMetadata", required = false) String additionalMetadata,
+ @ApiParam(value = "file to upload") @RequestPart(value = "file", required = false) MultipartFile file
+ );
+
+}
diff --git a/samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/PetApiClient.java b/samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/PetApiClient.java
new file mode 100644
index 00000000000..ed3b67c359a
--- /dev/null
+++ b/samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/PetApiClient.java
@@ -0,0 +1,8 @@
+package org.openapitools.api;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.openapitools.configuration.ClientConfiguration;
+
+@FeignClient(name="${pet.name:pet}", configuration = ClientConfiguration.class)
+public interface PetApiClient extends PetApi {
+}
diff --git a/samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/StoreApi.java b/samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/StoreApi.java
new file mode 100644
index 00000000000..9d5103b3177
--- /dev/null
+++ b/samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/StoreApi.java
@@ -0,0 +1,148 @@
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (6.0.0-SNAPSHOT).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+package org.openapitools.api;
+
+import java.util.Map;
+import org.openapitools.model.Order;
+import io.swagger.annotations.*;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import javax.annotation.Generated;
+
+@Generated(value = "org.openapitools.codegen.languages.SpringCodegen")
+@Validated
+@Api(value = "Store", description = "Access to Petstore orders")
+public interface StoreApi {
+
+ /**
+ * DELETE /store/order/{orderId} : Delete purchase order by ID
+ * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
+ *
+ * @param orderId ID of the order that needs to be deleted (required)
+ * @return Invalid ID supplied (status code 400)
+ * or Order not found (status code 404)
+ */
+ @ApiOperation(
+ tags = { "store" },
+ value = "Delete purchase order by ID",
+ nickname = "deleteOrder",
+ notes = "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors"
+ )
+ @ApiResponses({
+ @ApiResponse(code = 400, message = "Invalid ID supplied"),
+ @ApiResponse(code = 404, message = "Order not found")
+ })
+ @RequestMapping(
+ method = RequestMethod.DELETE,
+ value = "/store/order/{orderId}"
+ )
+ ResponseEntity deleteOrder(
+ @ApiParam(value = "ID of the order that needs to be deleted", required = true) @PathVariable("orderId") String orderId
+ );
+
+
+ /**
+ * GET /store/inventory : Returns pet inventories by status
+ * Returns a map of status codes to quantities
+ *
+ * @return successful operation (status code 200)
+ */
+ @ApiOperation(
+ tags = { "store" },
+ value = "Returns pet inventories by status",
+ nickname = "getInventory",
+ notes = "Returns a map of status codes to quantities",
+ response = Integer.class,
+ responseContainer = "Map",
+ authorizations = {
+ @Authorization(value = "api_key")
+ }
+ )
+ @ApiResponses({
+ @ApiResponse(code = 200, message = "successful operation", response = Map.class, responseContainer = "Map")
+ })
+ @RequestMapping(
+ method = RequestMethod.GET,
+ value = "/store/inventory",
+ produces = "application/json"
+ )
+ ResponseEntity