Java - как сгенерировать пользовательский интерфейс Swagger непосредственно из спецификации openapi 3.0

У меня есть спецификация openapi 3.0 в формате yaml и мое приложение, которое генерирует из нее код. Все работает нормально, кроме создания swagger ui. Я использую spring-fox для его генерации, но похоже, что он генерирует версию swagger ui 2.0 из контроллеров, которые сгенерированы из спецификации openapi.

Как я могу сгенерировать пользовательский интерфейс swagger непосредственно из моей спецификации 3.0, а не из контроллеров, которые созданы из спецификации 3.0 openapi?


person Sergei Podlipaev    schedule 17.04.2019    source источник
comment
Похоже, что springfox не поддерживает OAS 3.0 - github.com/springfox/springfox/issues/2022. Можете ли вы предложить какие-либо другие библиотеки, которые генерируют чванство из спецификации?   -  person Sergei Podlipaev    schedule 17.04.2019
comment
Пользовательский интерфейс Swagger доступен отдельно по адресу github.com/swagger-api/swagger-ui. и вы можете разместить его самостоятельно отдельно от кода приложения. Вы не генерируете его из спецификации OpenAPI, вместо этого вы берете пользовательский интерфейс Swagger и подключаете его к своей спецификации. См. Вопросы, связанные с ^^.   -  person Helen    schedule 17.04.2019


Ответы (1)


Что ж, я решил проблему (хотя решение довольно громоздкое).

Первым делом я добавил веб-сайт swagger ui -

        <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>

Затем я преобразовываю свою спецификацию yaml в формат json и копирую ее в каталог webjar swagger-ui:

            <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>

Далее нам нужно указать путь к спецификации в swagger-ui. Согласно swagger-ui API мы можем передать spec Переменная JSON вместо url. Итак, чтобы инициализировать эту переменную spec и отредактировать рендеринг пользовательского интерфейса swagger, я использую плагин replacer в 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>

Итак, на этом этапе после сборки мы получили статический ресурс с пользовательским интерфейсом swagger. Последнее, что нужно сделать, - это подать его вместе со 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");
    }
}

Так вот оно. Было бы здорово, если бы вы прокомментировали этот ответ и указали, как упростить эту процедуру.

person Sergei Podlipaev    schedule 25.04.2019
comment
Спасибо, Сергей, это тоже ОЧЕНЬ помогло мне решить мою проблему. Почему Sou выбрал переменную spec, в результате чего было произведено 3 замены? Замена url-адреса petstore.json на локальный openapi.json сработала для меня: <replacement><token>https:\/\/petstore\.swagger\.io\/v2\/swagger\.json</token<value>openapi.json</value></replacement> Я использовал вывод для документа gitlab pages. В этом случае мне пришлось удалить index.html.gz, поэтому на самом деле был поднят мой измененный index.html. - person Ralf; 20.09.2019
comment
@mineralf thx, я проверю. Также я планирую проверить, как создать пользовательский интерфейс Swagger из нескольких файлов спецификаций. Отправлю его здесь после того, как найду решение - person Sergei Podlipaev; 25.09.2019