Step 3: Advanced Swagger 3 Features – Spring Documentation Series

⚑ Step 3: Advanced Swagger 3 Features

πŸŽ₯ YouTube Video: Coming Soon – Subscribe to JavaiOS Channel


Swagger 3 Integration with Spring Cloud Gateway ⚑

This guide outlines the essential step-by-step setup for integrating Swagger 3 (OpenAPI 3) in a Spring Cloud microservices architecture, focusing on advanced configuration patterns and enterprise-level features for production deployments.

In the AdventureTube microservice architecture, this represents the final phase of documentation integration, implementing advanced Swagger 3 features and optimization techniques.


🧭 Overview

This advanced implementation builds upon the foundational SpringDoc integration and gateway aggregation to provide enterprise-grade API documentation with enhanced features, performance optimization, and production-ready configurations.

Advanced Features Covered:

  • Dependency Management – Proper WebMVC vs WebFlux dependency handling
  • Configuration Optimization – Advanced SpringDoc configuration patterns
  • Performance Tuning – Caching, lazy loading, and optimization techniques
  • Production Deployment – Enterprise-ready configuration and security

πŸ› οΈ Two-Phase Integration Overview

πŸ”Ή Phase 1: Individual Service Advanced Configuration

Each microservice is configured with advanced SpringDoc OpenAPI features including custom documentation, performance optimization, and enterprise-level configuration management.

Reference: Foundation setup in Step 1

πŸ”Ή Phase 2: Gateway Advanced Security and Routing

Advanced gateway configuration with sophisticated routing, security integration, and performance optimization for enterprise-scale documentation aggregation.

Reference: Gateway integration in Step 2


βœ… Step 1: Advanced Microservice Configuration

Each microservice requires advanced configuration to support enterprise-level documentation features and performance optimization.

πŸ”§ Dependency Management Strategy

Proper dependency selection is crucial for microservice vs gateway configuration:



  org.springdoc
  springdoc-openapi-starter-webmvc-ui
  ${spring-doc.version}

βœ… Use webmvc-ui because individual microservices are based on Spring MVC and require servlet-based documentation generation.

πŸ›  Advanced Configuration via Spring Cloud Config

Define comprehensive Swagger configuration per microservice using Git-backed configuration files in config-service.

Example for service configuration (e.g., web-service.yml):

springdoc:
  api-docs:
    path: /v3/api-docs
    enabled: true
    resolve-schema-properties: true
  swagger-ui:
    path: /swagger-ui.html
    enabled: true
    config-url: /v3/api-docs/swagger-config
    url: /v3/api-docs
    tryItOutEnabled: true
    operationsSorter: method
    tagsSorter: alpha
    deepLinking: true
    displayOperationId: false
    defaultModelsExpandDepth: 1
    defaultModelExpandDepth: 1
    defaultModelRendering: example
    displayRequestDuration: true
    docExpansion: none
    filter: false
    showExtensions: true
    showCommonExtensions: true
  cache:
    disabled: false
  override-with-generic-response: false
  remove-broken-reference-definitions: false

πŸ“ These files should be located under: config-service/src/main/resources/config/

πŸ” Configuration Validation

To ensure your microservice has correctly loaded the advanced configuration:

GET http://config.adventuretube.net/web-service/default
  • Replace web-service with your actual service name
  • Verify all SpringDoc properties are correctly loaded
  • Check for configuration conflicts or missing properties

πŸ§ͺ Advanced Service Configuration Results

After implementing advanced configuration:

  • Enhanced OpenAPI JSON: http://localhost:<port>/v3/api-docs
  • Advanced Swagger UI: http://localhost:<port>/swagger-ui.html
  • Configuration Endpoint: http://localhost:<port>/v3/api-docs/swagger-config

βœ… Step 2: Advanced Gateway Configuration

The API Gateway requires sophisticated configuration to handle WebFlux-based reactive documentation aggregation with enterprise-level features.

πŸ”§ WebFlux Dependency Management

Gateway services require WebFlux-specific dependencies:



  org.springdoc
  springdoc-openapi-starter-webflux-ui

⚠️ Critical: Use webflux-ui in the gateway because Spring Cloud Gateway is built on Spring WebFlux (reactive stack). Do not use webmvc-ui here as it will cause runtime conflicts.

🧩 Enterprise Dependency Management

To support scalable microservice architectures, define dependencies centrally in the parent POM:

In adventuretube-microservice/pom.xml:


  
    
    
      org.springdoc
      springdoc-openapi-starter-webmvc-ui
      ${spring-doc.version}
    
    
    
    
      org.springdoc
      springdoc-openapi-starter-webflux-ui
      ${spring-doc.version}
    
  

Then, in WebFlux-based modules (gateways, reactive APIs):


  org.springdoc
  springdoc-openapi-starter-webflux-ui

βœ… This approach keeps version management centralized and prevents dependency conflicts across the microservice ecosystem.


🌐 Advanced Gateway Routing Configuration

Implement sophisticated routing patterns in GatewayConfig.java:

@Configuration
public class AdvancedGatewayConfig {
    
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            // Documentation routes (no authentication filters)
            .route("auth-docs", r -> r.path("/auth-service/v3/api-docs")
                .filters(f -> f.stripPrefix(1)
                    .addResponseHeader("Cache-Control", "max-age=300")
                    .addResponseHeader("X-Documentation-Service", "auth-service"))
                .uri("lb://auth-service"))
                
            .route("member-docs", r -> r.path("/member-service/v3/api-docs")
                .filters(f -> f.stripPrefix(1)
                    .addResponseHeader("Cache-Control", "max-age=300")
                    .addResponseHeader("X-Documentation-Service", "member-service"))
                .uri("lb://member-service"))
                
            .route("web-docs", r -> r.path("/web-service/v3/api-docs")
                .filters(f -> f.stripPrefix(1)
                    .addResponseHeader("Cache-Control", "max-age=300")
                    .addResponseHeader("X-Documentation-Service", "web-service"))
                .uri("lb://web-service"))
                
            .route("geo-docs", r -> r.path("/geo-service/v3/api-docs")
                .filters(f -> f.stripPrefix(1)
                    .addResponseHeader("Cache-Control", "max-age=300")
                    .addResponseHeader("X-Documentation-Service", "geospatial-service"))
                .uri("lb://geospatial-service"))
            
            // Main API routes with authentication filters
            .route("auth-service", r -> r.path("/auth-service/**")
                .filters(f -> f.stripPrefix(1).filter(authenticationFilter))
                .uri("lb://auth-service"))
                
            // Additional service routes...
            .build();
    }
}

🚫 Important: Do not apply authentication filters to documentation routes to ensure Swagger UI can fetch API docs without authentication.

πŸ“˜ Advanced Swagger UI Aggregation

Configure comprehensive documentation aggregation in application.yml:

springdoc:
  swagger-ui:
    enabled: true
    path: /swagger-ui.html
    config-url: /v3/api-docs/swagger-config
    urls:
      - name: Auth Service
        url: /auth-service/v3/api-docs
        display-name: "Authentication & Authorization API"
      - name: Member Service
        url: /member-service/v3/api-docs
        display-name: "Member Management API"
      - name: Web Service
        url: /web-service/v3/api-docs
        display-name: "Web Application API"
      - name: Geospatial Service
        url: /geo-service/v3/api-docs
        display-name: "Location & Mapping API"
    operationsSorter: method
    tagsSorter: alpha
    tryItOutEnabled: true
    filter: true
    syntaxHighlight:
      activated: true
      theme: agate
    deepLinking: true
    displayOperationId: false
    defaultModelsExpandDepth: 1
    defaultModelExpandDepth: 1
    defaultModelRendering: example
    displayRequestDuration: true
    docExpansion: list
    maxDisplayedTags: 50
    showExtensions: true
    showCommonExtensions: true
    persistAuthorization: true
  api-docs:
    enabled: true
    path: /v3/api-docs
  cache:
    disabled: false

πŸš€ Advanced Performance Optimization

1. Documentation Caching Strategy

@Configuration
public class DocumentationCacheConfig {
    
    @Bean
    public CacheManager documentationCacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(Caffeine.newBuilder()
            .maximumSize(100)
            .expireAfterWrite(5, TimeUnit.MINUTES)
            .recordStats());
        return cacheManager;
    }
    
    @Bean
    @ConfigurationProperties("springdoc.cache")
    public CacheProperties springdocCacheProperties() {
        return new CacheProperties();
    }
}

2. Lazy Loading Configuration

springdoc:
  lazy-initialization: true
  api-docs:
    resolve-schema-properties: true
  swagger-ui:
    lazy: true
    use-root-path: false

3. Resource Optimization

@Configuration
public class SwaggerResourceOptimization {
    
    @Bean
    public WebFluxConfigurer webFluxConfigurer() {
        return new WebFluxConfigurer() {
            @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry) {
                registry.addResourceHandler("/swagger-ui/**")
                    .addResourceLocations("classpath:/META-INF/resources/webjars/swagger-ui/")
                    .setCachePeriod(3600)
                    .resourceChain(true)
                    .addResolver(new PathResourceResolver());
            }
        };
    }
}

πŸ”’ Enterprise Security Integration

1. Advanced Authentication Configuration

@Configuration
public class SwaggerSecurityConfig {
    
    @Bean
    public OpenApiCustomiser openApiCustomiser() {
        return openApi -> {
            // Add security schemes
            openApi.addSecurityItem(new SecurityRequirement().addList("bearer-jwt"))
                .getComponents()
                .addSecuritySchemes("bearer-jwt", new SecurityScheme()
                    .type(SecurityScheme.Type.HTTP)
                    .scheme("bearer")
                    .bearerFormat("JWT")
                    .description("JWT Authorization header using the Bearer scheme"));
                    
            // Add server information
            openApi.addServersItem(new Server()
                .url("https://api.adventuretube.net")
                .description("Production API Gateway"));
                
            openApi.addServersItem(new Server()
                .url("https://staging-api.adventuretube.net")
                .description("Staging Environment"));
        };
    }
}

2. Environment-Specific Configuration

# Production profile (application-prod.yml)
springdoc:
  swagger-ui:
    enabled: false  # Disable in production
  api-docs:
    enabled: true   # Keep API docs for internal tools

# Development profile (application-dev.yml)  
springdoc:
  swagger-ui:
    enabled: true
    tryItOutEnabled: true
  api-docs:
    enabled: true

# Staging profile (application-staging.yml)
springdoc:
  swagger-ui:
    enabled: true
    tryItOutEnabled: false  # Read-only in staging
  api-docs:
    enabled: true

πŸ“Š Monitoring and Metrics

Documentation Usage Metrics

@Component
public class SwaggerMetrics {
    
    private final MeterRegistry meterRegistry;
    private final Counter documentationAccessCounter;
    private final Timer documentationLoadTimer;
    
    public SwaggerMetrics(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        this.documentationAccessCounter = Counter.builder("swagger.access")
            .description("Number of documentation page accesses")
            .register(meterRegistry);
        this.documentationLoadTimer = Timer.builder("swagger.load.duration")
            .description("Time taken to load documentation")
            .register(meterRegistry);
    }
    
    @EventListener
    public void handleDocumentationAccess(SwaggerAccessEvent event) {
        documentationAccessCounter.increment(
            Tags.of("service", event.getServiceName(),
                   "endpoint", event.getEndpoint()));
    }
}

⚠️ Production Deployment Considerations

1. Security Hardening

  • Disable Swagger UI in Production: Use profiles to control documentation exposure
  • API Documentation Access Control: Implement role-based access for documentation endpoints
  • Rate Limiting: Add rate limiting to documentation endpoints to prevent abuse
  • Content Security Policy: Configure CSP headers for Swagger UI pages

2. Performance Monitoring

# Actuator configuration for monitoring
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,swagger
  endpoint:
    swagger:
      enabled: true
  metrics:
    tags:
      application: adventuretube-gateway
      service: documentation

3. Error Handling

@ControllerAdvice
public class SwaggerErrorHandler {
    
    @ExceptionHandler(SwaggerResourceNotFoundException.class)
    public ResponseEntity handleSwaggerResourceNotFound(
            SwaggerResourceNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND)
            .body(new ErrorResponse("Documentation resource not found", ex.getMessage()));
    }
    
    @ExceptionHandler(SwaggerConfigurationException.class)
    public ResponseEntity handleSwaggerConfiguration(
            SwaggerConfigurationException ex) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body(new ErrorResponse("Documentation configuration error", ex.getMessage()));
    }
}

βœ… Advanced Implementation Checklist

Dependency Management βœ…

  • βœ… Correct WebMVC vs WebFlux dependency selection
  • βœ… Centralized version management in parent POM
  • βœ… No dependency conflicts between services
  • βœ… Proper Spring Boot compatibility

Performance Optimization βœ…

  • βœ… Documentation caching implemented
  • βœ… Lazy loading configuration
  • βœ… Resource optimization and compression
  • βœ… Response header caching strategy

Security & Production βœ…

  • βœ… Environment-specific configuration
  • βœ… Production security hardening
  • βœ… Authentication integration
  • βœ… Rate limiting and abuse prevention

Monitoring & Maintenance βœ…

  • βœ… Usage metrics and monitoring
  • βœ… Error handling and logging
  • βœ… Health checks for documentation services
  • βœ… Performance monitoring integration

🎯 Enterprise-Grade Results

Feature Basic Implementation Advanced Implementation
Dependency Management Manual per-service configuration Centralized parent POM management
Performance Default loading and caching Optimized caching and lazy loading
Security Basic endpoint protection Environment-specific security policies
Monitoring Basic health checks Comprehensive metrics and monitoring
Production Readiness Development-focused Enterprise deployment ready

πŸŽ‰ Documentation Journey Complete!

🧭 Complete Spring Documentation Series:

Part of the AdventureTube technical blog series supporting the JavaiOS YouTube channel.

Leave a Comment

Your email address will not be published. Required fields are marked *