9

I have a Spring Boot Application and I use openapi-generator-maven-plugin for generating rest client. I want to have a option to change url during runtime.

The url of the rest server is now hardcoded in the following snippet of OpenAPI definition:

openapi: 3.0.1
info:
  title: OpenAPI definition
  version: v0
servers:
  - url: 'http://localhost:8080'
    description: Generated server url

Configuration of the maven plugin:

            <plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>4.3.1</version>
<execution>
                        <id>vydejClient</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>
                                ${project.basedir}/src/main/resources/manualni_kodovani_vydej.yaml
                            </inputSpec>
                            <generatorName>java</generatorName>
                            <generateApiTests>false</generateApiTests>
                            <generateModelTests>false</generateModelTests>
                            <configOptions>
                                <dateLibrary>java8</dateLibrary>
                            </configOptions>
                            <library>resttemplate</library>
                            <typeMappings>
                                <typeMapping>File=org.springframework.core.io.Resource</typeMapping>
                            </typeMappings>
                            <apiPackage>client</apiPackage>
                            <modelPackage>client.model</modelPackage>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

This code is generated

@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2020-11-23T14:40:42.232315+01:00[Europe/Prague]")
@Component("ApiClient")
public class ApiClient {
    ...
    private String basePath = "http://localhost:8080";
    ...
     /**
     * Set the base path, which should include the host
     * @param basePath the base path
     * @return ApiClient this client
     */
    public ApiClient setBasePath(String basePath) {
        this.basePath = basePath;
        return this;
    }


}

I need to have this attribute configurable. Any idea how to do it?

2
  • 1
    Did you manage to implement this? Can you share how? Thanks. Commented Jun 9, 2021 at 10:57
  • Did you get how to do this? can you share please? Commented Jan 19, 2023 at 14:49

2 Answers 2

1

You can set up an ApiClient bean modifying its base path, and define a bean for your generated api using this modified ApiClient. This setup allows your application to make API calls with the configured base URL.

@Configuration 
public class YourGeneratedApiConfig {
  
  @Value("${rest.clients.yourGeneratedApi.endpoint}")
  private String endpoint;

  // Create a RestTemplate bean using RestTemplateBuilder
  @Bean 
  public RestTemplate restTemplate (RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.build();
  }
  
  // Create an ApiClient bean and overwrite its base path to the configured one
  @Bean 
  public ApiClient apiclient(RestTemplate restTemplate) {
    ApiClient apiclient = new ApiClient(restTemplate);
    apiclient.setBasePath(endpoint);
    return apiclient; 
  }

  // Create a YourGeneratedApi bean using the configured ApiClient
  @Bean 
  public YourGeneratedApi yourGeneratedApi(ApiClient apiclient) {
    return new YourGeneratedApi(apiClient);
  }


  // If you have multiple apis in the same base path 
  // then create AnotherGeneratedApi bean using the same api client
  @Bean 
  public AnotherGeneratedApi anotherGeneratedApi(ApiClient apiClient) {
    return new AnotherGeneratedApi(apiClient);
  }
}

Add the endpoint URL to your application.properties or application.yml file.

rest.clients.yourGeneratedApi.endpoint=https://api.example.com

Create a service class that uses the YourGeneratedApi bean.

@Service
public class YourService {

  private final YourGeneratedApi yourGeneratedApi;

  @Autowired
  public YourService(YourGeneratedApi yourGeneratedApi) {
    this.yourGeneratedApi = yourGeneratedApi;
  }

  public void performApiCall() {
    // Example method call on yourGeneratedApi
    yourGeneratedApi.someApiMethod();
  }
}

Note: If you have generateClientAsBean defined as true (default false) in your openapi-generator-maven-plugin configuration then you should remove it because now we are creating the ApiClient bean manually so we don't want the @Component annotation to be generated in the ApiClient class.

Sign up to request clarification or add additional context in comments.

5 Comments

How to inject that? Or is it @Autowired into generated code automatically?
What do you mean by "automatically"? I'm creating a bean here, and the constructor parameter of your generated API code is an ApiClient with a modified base URL that i'm setting to create the bean with new YourGeneratedApi(apiClient) This bean is then used in your service. I have updated my answer for clarity.
@u4963840 Uoops fixed a bug in my answer I was not passing the apiClient as parameter here public YourGeneratedApi yourGeneratedApi(ApiClient apiclient) { ... }, maybe that was what you were refering to?
Yes. For those who are new to Spring @Autowired above constructor of YourService is same as @Autowire YourGeneratedApi yourGeneratedApi;
@u4963840 Exactly! It's generally considered best practice to use constructor injection. Classes with a single constructor can even omit the @Autowired annotation, so I could have omitted it. If you're using Lombok, you can add instead @RequiredArgsConstructor to the class and mark the injected field as final private final YourGeneratedApi yourGeneratedApi, the constructor will be generated, and the final fields will be injected automatically.
0

Did you try using <serverVariableOverrides>? See the answer here: OpenAPI 3 path substitution with openapi-generator-maven-plugin.

Also consider using maven-replacer-plugin. See the working example in this question: maven-replacer-plugin and multiple files

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.