Устранить ошибку 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, настроенной так:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>
В application.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.
В конфигурации безопасности у меня:
@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» в продакшене?
Общие причины ошибки
Несколько факторов могут вызвать эту ошибку при переходе из локальной среды в продакшн:
-
Несоответствие путей:
config-urlвapplication.propertiesне совпадает с реальной структурой конечных точек API‑документации в продакшене. Согласно исследованиям, это самая частая причина ошибок «No API Definition Provided» источник. -
Проблемы с контекстным путем: При использовании сложных контекстных путей, например
/applicationname/rest/env1, относительные пути в Swagger UI могут не разрешаться корректно источник. -
Несоответствие шаблонов безопасности: Конфигурация безопасности может не правильно сопоставлять все необходимые конечные точки для работы Swagger UI источник.
-
Поведение по умолчанию URL: Свойство
disable-default-urlможет не работать как ожидается в продакшн‑среде источник.
Исправления конфигурации
Корректная настройка путей
Ваша текущая конфигурация содержит несоответствие между config-url и реальным путем API‑документации. Вот исправление:
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 источник.
Альтернативный подход к конфигурации
Вы также можете настроить это программно для большего контроля:
@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();
}
}
Проблемы конфигурации безопасности
Ваша текущая конфигурация безопасности пропускает несколько важных шаблонов. Вот исправленная версия:
@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:
@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:
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 в продакшне по соображениям безопасности. Вы можете сделать это так:
# application-prod.properties
springdoc.swagger-ui.enabled=false
springdoc.api-docs.enabled=false
Шаги отладки
- Проверьте доступ к API‑документации: Убедитесь, что вы можете получить доступ к API‑документации напрямую по настроенному URL.
- Проверьте сетевые запросы: Используйте инструменты разработчика браузера, чтобы увидеть, какие запросы не проходят при загрузке Swagger UI.
- Проверьте
config-url: Убедитесь, чтоconfig-urlточно совпадает с местом, где обслуживается конфигурация Swagger. - Тестируйте без безопасности: Временно удалите ограничения безопасности, чтобы изолировать проблему.
- Проверьте наличие конфликтующих конфигураций: Убедитесь, что у вас нет конфликтующих настроек SpringDoc источник.
- Проверьте зависимости: Убедитесь, что вы используете правильный starter‑dependency SpringDoc для Spring Boot 3 источник.
Источники
- SpringDoc OpenAPI FAQ - Configuration Issues
- Stack Overflow - No API definition provided error
- SpringDoc OpenAPI GitHub Issues - Path Configuration
- Baeldung - Spring REST OpenAPI Documentation
- Medium - Spring Boot Swagger Setup
- Stack Overflow - Custom SpringDoc Configuration
Заключение
Чтобы решить ошибку «No API Definition Provided» в продакшн‑среде:
- Обновите конфигурацию путей так, чтобы они соответствовали полной структуре контекстного пути.
- Улучшите шаблоны безопасности, чтобы включить все необходимые конечные точки Swagger.
- Рассмотрите конфигурацию, специфичную для окружения, для разных стадий развертывания.
- Реализуйте правильную настройку URL для сложных продакшн‑структур.
- Следуйте лучшим практикам безопасности, возможно, отключив Swagger в продакшне.
Ключевая проблема, скорее всего, в том, что свойства config-url и api-docs.path не учитывают полный контекстный путь (/applicationname/rest/env1/), который существует в продакшне, но отсутствует в локальной среде разработки. Убедившись, что все пути правильно настроены с полным контекстным путем, вы должны решить проблему загрузки определения API.