Другое

Устранить ошибку Swagger No API Definition в Spring Boot 3

Решите проблему Swagger 'No API Definition Provided' в Spring Boot 3: настройка путей, безопасность, контекстные пути и окружения, и советы по продакшн развертыванию.

Spring Boot 3 Swagger «No API Definition Provided» ошибка в продакшене

У меня есть приложение Spring Boot 3 с зависимостью springdoc-openapi, настроенной так:

xml
<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
  <version>2.5.0</version>
</dependency>

В application.properties я добавил следующие свойства:

properties
springdoc.swagger-ui.path=/swagger-ui.html
springdoc.swagger-ui.config-url=/applicationname/rest/env1/api-docs/swagger-config
springdoc.swagger-ui.disable-default-url=true
springdoc.api-docs.path=/api-docs

Swagger UI работает локально по адресу http://localhost:8080/swagger-ui.html, но после деплоя в env1 появляется ошибка «No API Definition Provided». Контекст приложения – https://domain/applicationname/rest/env1, и я открываю Swagger по адресу https://domain/applicationname/rest/env1/swagger-ui.html.

Я могу успешно получить API‑документы напрямую по https://domain/applicationname/rest/env1/api-docs.

В конфигурации безопасности у меня:

java
@Bean
@Order(1)
public SecurityFilterChain publicChain(HttpSecurity http){
    http.authoriseRequests(req -> req.requestMatchers(
            "/swagger-ui.html",
            "/swagger-ui.html/**",
            "/api-docs",
            "/v3/api-docs",
            "v3/api-docs/**",
            "/api-docs/**")
        .permitAll()
        .anyRequest().permitAll());
    return http.build();
}

@Bean
@Order(2)
public SecurityFilterChain privateChain(HttpSecurity http){
    http.authoriseRequests(req -> req.requestMatchers("/api/test**")
        .hasRole(ROLE)
        .anyRequest().permitAll());
    return http.build();
}

Как исправить ошибку «No API Definition Provided» в продакшене?

Общие причины ошибки

Несколько факторов могут вызвать эту ошибку при переходе из локальной среды в продакшн:

  1. Несоответствие путей: config-url в application.properties не совпадает с реальной структурой конечных точек API‑документации в продакшене. Согласно исследованиям, это самая частая причина ошибок «No API Definition Provided» источник.

  2. Проблемы с контекстным путем: При использовании сложных контекстных путей, например /applicationname/rest/env1, относительные пути в Swagger UI могут не разрешаться корректно источник.

  3. Несоответствие шаблонов безопасности: Конфигурация безопасности может не правильно сопоставлять все необходимые конечные точки для работы Swagger UI источник.

  4. Поведение по умолчанию URL: Свойство disable-default-url может не работать как ожидается в продакшн‑среде источник.

Исправления конфигурации

Корректная настройка путей

Ваша текущая конфигурация содержит несоответствие между config-url и реальным путем API‑документации. Вот исправление:

properties
springdoc.swagger-ui.path=/swagger-ui.html
springdoc.swagger-ui.config-url=/applicationname/rest/env1/api-docs/swagger-config
springdoc.swagger-ui.disable-default-url=true
springdoc.api-docs.path=/applicationname/rest/env1/api-docs

Обратите внимание, что config-url должен совпадать с базовым путем, где обслуживается ваша API‑документация, а не включать суффикс /swagger-config на этом уровне. Согласно исследованиям, config-url должен указывать на место, откуда будет загружаться конфигурационный файл Springdoc источник.

Альтернативный подход к конфигурации

Вы также можете настроить это программно для большего контроля:

java
@Configuration
public class SwaggerConfig {
    
    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
            .info(new Info()
                .title("API Documentation")
                .version("1.0")
                .description("API Documentation"));
    }
    
    @Bean
    public GroupedOpenApi publicApi() {
        return GroupedOpenApi.builder()
            .group("public")
            .pathsToMatch("/api/**")
            .build();
    }
}

Проблемы конфигурации безопасности

Ваша текущая конфигурация безопасности пропускает несколько важных шаблонов. Вот исправленная версия:

java
@Bean
@Order(1)
public SecurityFilterChain publicChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(authz -> authz
        .requestMatchers(
            "/swagger-ui.html",
            "/swagger-ui.html/**",
            "/swagger-ui/**",
            "/swagger-resources/**",
            "/v3/api-docs",
            "/v3/api-docs/**",
            "/api-docs",
            "/api-docs/**",
            "/applicationname/rest/env1/swagger-ui.html",
            "/applicationname/rest/env1/swagger-ui.html/**",
            "/applicationname/rest/env1/api-docs",
            "/applicationname/rest/env1/api-docs/**"
        ).permitAll()
        .anyRequest().permitAll()
    );
    return http.build();
}

Ключевые дополнения:

  • /swagger-ui/** – покрывает все ресурсы Swagger UI
  • /swagger-resources/** – покрывает файлы ресурсов Swagger
  • Полные контекстные пути для продакшн‑среды

Согласно исследованиям из Baeldung, правильная конфигурация безопасности критична для корректной работы Swagger UI.

Решения для продакшн‑среды

Настройка базового URL сервера

Для продакшн‑сред с сложной структурой URL реализуйте ServerBaseUrlCustomizer:

java
@Component
public class CustomServerBaseUrlCustomizer implements ServerBaseUrlCustomizer {
    
    @Override
    public void customize(Server server) {
        String baseUrl = "https://domain/applicationname/rest/env1";
        server.setUrl(baseUrl);
    }
}

Конфигурация, специфичная для окружения

Создайте конфигурации, зависящие от профиля:

application-prod.properties:

properties
springdoc.swagger-ui.path=/applicationname/rest/env1/swagger-ui.html
springdoc.swagger-ui.config-url=/applicationname/rest/env1/api-docs/swagger-config
springdoc.api-docs.path=/applicationname/rest/env1/api-docs
springdoc.swagger-ui.disable-default-url=true
springdoc.swagger-ui.try-it-out-enabled=true

Отключение Swagger в продакшне (лучшие практики безопасности)

Согласно исследованиям из Medium, лучшей практикой является отключение Swagger в продакшне по соображениям безопасности. Вы можете сделать это так:

properties
# application-prod.properties
springdoc.swagger-ui.enabled=false
springdoc.api-docs.enabled=false

Шаги отладки

  1. Проверьте доступ к API‑документации: Убедитесь, что вы можете получить доступ к API‑документации напрямую по настроенному URL.
  2. Проверьте сетевые запросы: Используйте инструменты разработчика браузера, чтобы увидеть, какие запросы не проходят при загрузке Swagger UI.
  3. Проверьте config-url: Убедитесь, что config-url точно совпадает с местом, где обслуживается конфигурация Swagger.
  4. Тестируйте без безопасности: Временно удалите ограничения безопасности, чтобы изолировать проблему.
  5. Проверьте наличие конфликтующих конфигураций: Убедитесь, что у вас нет конфликтующих настроек SpringDoc источник.
  6. Проверьте зависимости: Убедитесь, что вы используете правильный starter‑dependency SpringDoc для Spring Boot 3 источник.

Источники

  1. SpringDoc OpenAPI FAQ - Configuration Issues
  2. Stack Overflow - No API definition provided error
  3. SpringDoc OpenAPI GitHub Issues - Path Configuration
  4. Baeldung - Spring REST OpenAPI Documentation
  5. Medium - Spring Boot Swagger Setup
  6. Stack Overflow - Custom SpringDoc Configuration

Заключение

Чтобы решить ошибку «No API Definition Provided» в продакшн‑среде:

  1. Обновите конфигурацию путей так, чтобы они соответствовали полной структуре контекстного пути.
  2. Улучшите шаблоны безопасности, чтобы включить все необходимые конечные точки Swagger.
  3. Рассмотрите конфигурацию, специфичную для окружения, для разных стадий развертывания.
  4. Реализуйте правильную настройку URL для сложных продакшн‑структур.
  5. Следуйте лучшим практикам безопасности, возможно, отключив Swagger в продакшне.

Ключевая проблема, скорее всего, в том, что свойства config-url и api-docs.path не учитывают полный контекстный путь (/applicationname/rest/env1/), который существует в продакшне, но отсутствует в локальной среде разработки. Убедившись, что все пути правильно настроены с полным контекстным путем, вы должны решить проблему загрузки определения API.

Авторы
Проверено модерацией
Модерация