Агрегация спецификаций в одном 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;
    }

не знаю по поводу бестпрактик, увы не нашёл нигде конкретных реализаций, но работает.

Если кто знает как это реализуется проще и лучше - буду рад выслушать.

→ Ссылка