Агрегация спецификаций в одном Swagger UI
(увы не силён в микросервисах)
Исходные данные: Проект на Java, 7 сервисов.
Между собой дружат через gateway с помощью Kafka.
Поставили задачу сделать единый Swagger UI на все endpoints Все варианты которые нашел, либо реализация через эврику(как то не вяжется в одном app с kafka), либо mvc (не вяжется с реактивом).
Подскажите пожалуйста - в какую сторону копать?
Ответы (1 шт):
Решение оказалась простым. Сделали отдельный сервис swagger для каждого сервиса прописали роуты(например)
public RouterFunction<ServerResponse> authServiceSwaggerRoute() {
return GatewayRouterFunctions.route("auth")
.route(RequestPredicates.path("/auth-service/api-docs"), HandlerFunctions.http("http://localhost:8080"))
.filter(setPath("/auth-service/api-docs"))
.build();
}
- создали группы
public GroupedOpenApi authOpenApi() {
String[] paths = {"/auth-service/**"};
return GroupedOpenApi.builder().group("auth").pathsToMatch(paths)
.build();
}
прописали пути+имена групп в конфиге(например)
springdoc:
swagger-ui:
path: /swagger-ui.html
enabled: true
urls:
- name: auth
url: /auth-service/api-docs
- name: profile
url: /profile-service/api-docs
- name: file
url: /file-service/api-docs
api-docs:
enabled: true
и да, незабываем про секюрку в свагер сервисе что то типо:
private final String[] freeResourceUrls = {"/swagger-ui.html", "/swagger-ui/**", "/api-docs/**", "/v3/api-docs/**", "/swagger-resources/**", "/aggregate/**",
"/auth-service/swagger-ui.html", "/auth-service/api-docs",
"/file-service/swagger-ui.html", "/file-service/api-docs",
"/profile-service/swagger-ui.html", "/profile-service/api-docs"};
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity.authorizeHttpRequests(authorize -> authorize
.requestMatchers(freeResourceUrls).permitAll()
.anyRequest().authenticated())
.cors(corsConfigurer -> corsConfigurer.configurationSource(corsConfigSource()))
.build();
}
ну и конечно CORS, у нас ведь сервисы на разных портах, по этому во всех сервисах которые хотите видеть в одном свагере нужно прописать разрешение что то типа:
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("http://localhost:8280");//тут укажите порт своего сваггера
configuration.addAllowedMethod("*");
configuration.addAllowedHeader("*");
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
не знаю по поводу бестпрактик, увы не нашёл нигде конкретных реализаций, но работает.
Если кто знает как это реализуется проще и лучше - буду рад выслушать.