Search code examples
swaggerswagger-2.0swagger-codegennetflix-feignfeign

how to generate URI parameter for dynamic feign basePath using swagger codegen?


I have a pretty simple question :)

According to feign documents, they are supporting in changing the basePath of a feign client object dynamically by passing URI parameter trough the api function like so:

GOOD Example:

interface MyClient {
    @RequestLine("GET /internal-service")
    String internalService(URI baseUrl);
}

The thing is I'm using swagger, who generates my API from a yaml file and adding @Param annotation to all function parameters, which is not good for me.

BAD Example:

interface MyClient {
    @RequestLine("GET {baseUrl}/internal-service")
    String internalService(@Param("baseUrl") String host);
}

Is there a way to make swagger generator to generate an API with a URI param, without the @Param annotation?

Desired Outcome Example:

interface MyClient {
    @RequestLine("POST /internal-service")
    String internalService(URI baseUrl, @Param("someParam") String someParam);
}

Solution

  • Initial solution:

    After some investigation I came to realize that there is no support in swagger-codegen 2.2.3 for generating URI parameter as part of the client API function.

    But there is an option in swagger-codegen-maven-plugin configuration of "templateDirectory - directory with mustache templates", for giving a path to a folder including mustache templates, which will take the templates in that folder and override the existing with the same name.

    example:

            <plugin>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-codegen-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>my-project-api-client-kit</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>${project.build.directory}/my-project-api.yaml</inputSpec>
                            <language>java</language>
                            <configOptions>
                                <dateLibrary>java8</dateLibrary>
                                <sourceFolder>src/main/java</sourceFolder>
                            </configOptions>
                            <modelPackage>my.project.ck.resources.models</modelPackage>
                            <apiPackage>my.project.ck.resources.interfaces</apiPackage>
                            <library>feign</library>
                            <templateDirectory>/myTemplateFolder/</templateDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
    

    And inside the custom templates folder, put your own api.mustache file with the additional "URI basePath" parameter:

    ...
    {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}(URI basePath, {{#allParams}}{{^isBodyParam}}{{^legacyDates}}@Param("{{paramName}}") {{/legacyDates}}{{#legacyDates}}@Param(value="{{paramName}}", expander=ParamExpander.class) {{/legacyDates}}{{/isBodyParam}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
    ...
    

    Note: Swagger provides a lot of templates for a variety of uses, make sure to take and modify the correct api.mustache template file according to which you are using. in the above example I modified (and override) the java.libraries.feign/api.mustache file because this is the file my plugin is configured too (as in the example).