Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - how to generate Swagger UI directly from openapi 3.0 specification

I have openapi 3.0 specification in yaml format and my application that generates code from it. Everything works fine except generation of swagger ui. I use spring-fox for its generation, but it seems like it generates swagger ui 2.0 version from controllers, that are generated from openapi specification.

How can I generate swagger ui directly from my 3.0 spec and not from controllers, that are generated from 3.0 openapi spec?

like image 831
Sergei Podlipaev Avatar asked Apr 17 '19 13:04

Sergei Podlipaev


People also ask

How do I download Swagger from OpenAPI?

Download from SwaggerHub EditorOpen the API in the SwaggerHub editor. If the API has several versions, select the version you want to download. From the Export menu, select Download API, and then select the desired format – YAML or JSON.

How do I get to Swagger UI?

By default, web servers default to the index. html file in the directory, so it will show the Swagger UI file automatically. If the browser doesn't direct to index. html , add it manually: http://localhost:8000/index.html .

How do I switch from OpenAPI 3 to Swagger 2?

If you need to import a REST web-service that only has an OpenAPI v3 specification you can use https://www.apimatic.io/ to convert it to Swagger 2 (the type that the development studio needs).


1 Answers

Well I have solved the problem (the solution is pretty cumbersome though).

First of all I added swagger ui webjar -

        <plugin>
            <!-- Download Swagger UI webjar. -->
            <artifactId>maven-dependency-plugin</artifactId>
            <version>${maven-dependency-plugin.version}</version>
            <executions>
                <execution>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>unpack</goal>
                    </goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>org.webjars</groupId>
                                <artifactId>swagger-ui</artifactId>
                                <version>${swagger-ui.version}</version>
                            </artifactItem>
                        </artifactItems>
                        <outputDirectory>${project.build.directory}/classes</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Then I transform my yaml specification to json format and copy it to swagger-ui webjar directory:

            <plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>4.0.0-beta3</version>
                <executions>                    
                    <execution>
                        <id>generate-spec</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>${openapi-spec-file-location}</inputSpec>
                            <validateSpec>true</validateSpec>
                            <generatorName>openapi</generatorName>
                            <output>${project.build.directory}/classes/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}</output>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Next we need to set specification path in swagger-ui. According to swagger-ui API we can pass spec JSON variable instead of url. So to initialize this spec variable and to edit swagger ui rendering I use replacer plugin in maven:

            <plugin>
                <!-- Replace the OpenAPI specification example URL with the local one. -->
                <groupId>com.google.code.maven-replacer-plugin</groupId>
                <artifactId>replacer</artifactId>
                <version>1.5.3</version>
                <executions>
                    <execution>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>replace</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <includes>
                        <!-- Static index html with swagger UI rendering and OAS in JSON format. -->
                        <include>${project.build.directory}/classes/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/index.html</include>
                        <include>${project.build.directory}/classes/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/openapi.json</include>
                    </includes>
                    <regexFlags>
                        <regexFlag>CASE_INSENSITIVE</regexFlag>
                        <regexFlag>MULTILINE</regexFlag>
                    </regexFlags>
                    <replacements>
                        <!-- This replacement imports spec json variable into static html page. -->
                        <replacement>
                            <token>&lt;script&gt;</token>
                            <value>&lt;script src="./openapi.json"&gt; &lt;/script&gt;&lt;script&gt;</value>
                        </replacement>
                        <!-- This part replaces url input variable with spec variable. -->
                        <replacement>
                            <token>url:\s"https:\/\/petstore\.swagger\.io\/v2\/swagger\.json"</token>
                            <value>spec: spec</value>
                        </replacement>
                        <replacement>
                        <!-- This replacement initializes spec variable, that will be passed to swagger ui index.html. -->
                            <token>^\{</token>
                            <value>spec = {</value>
                        </replacement>
                    </replacements>
                </configuration>
            </plugin>

So at this step after build we got static resource with swagger ui. Last thing to do is to serve it with Spring.

@Configuration
@EnableWebMvc
public class SwaggerConfiguration implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/swagger-ui/3.22.0/");
    }

    //this method was introduced just for convenient swagger ui access. Without it swagger ui can be accessed with /index.html GET call   
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/swagger-ui.html").setViewName("forward:/index.html");
    }
}

So this is it. It would be great if you comment this answer and point on how to simplify this procedure.

like image 85
Sergei Podlipaev Avatar answered Sep 23 '22 14:09

Sergei Podlipaev