11

I have multiple microservices, for which swagger has already been implemented. I would like to bring all the api's under single swagger UI. I've followed the following link for doing this. but tried it in maven approach in STS. Swagger Consilidation Github example

Here are my different files in the project,

@SpringBootApplication
@ComponentScan
@EnableAutoConfiguration
@EnableSwagger2
public class SgtestApplication {

    public static void main(String[] args) {
        SpringApplication.run(SgtestApplication.class, args);
    }

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() 
                  .apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.boot")))
                  .apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.cloud")))
                  .apis(Predicates.not(RequestHandlerSelectors.basePackage("org.springframework.security")))
                     .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Single swagger")
                .description("API to retrieve swagger apis")
                .version("1.0.0")
                .build();
    }
}

My resource provider is as follows,

@Component
@Primary
@EnableAutoConfiguration
public class GatewaySwaggerResourceProvider implements SwaggerResourcesProvider {

    @Autowired
    private SwaggerServicesConfig swaggerServiceList;

    public GatewaySwaggerResourceProvider() {
    }

    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();

        List<SwaggerServices> servList=swaggerServiceList.getServiceList();
        for (SwaggerServices swaggerServices : servList) {
            resources.add(swaggerResource(swaggerServices.getName(), swaggerServices.getUrl(),swaggerServices.getVersion()));
        }
        /*swaggerServiceList.getServiceList().forEach(service -> {
            resources.add(swaggerResource(service.getName(), service.getUrl(), service.getVersion()));
        });*/
        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location, String version) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion(version);
        return swaggerResource;
    }
}

and finally my service configuration,

@Component
@EnableAutoConfiguration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "documentation.swagger")
public class SwaggerServicesConfig {

    List<SwaggerServices> swagger;

    public List<SwaggerServices> getServiceList() {
        return swagger;
    }

    public void setServiceList(List<SwaggerServices> swaggerResources) {
        this.swagger = swaggerResources;
    }

    @EnableConfigurationProperties
    @ConfigurationProperties(prefix = "documentation.swagger.services")
    public static class SwaggerServices {
        private String name;
        private String url;
        private String version;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getVersion() {
            return version;
        }

        public void setVersion(String version) {
            this.version = version;
        }

        @Override
        public String toString() {
            return "SwaggerServices [name=" + name + ", url=" + url + ", version=" + version + "]";
        }

    }

}

in my application.yml i am specifying the api docs endpoint of different microservices.

spring:
  profiles: default

server:
  port: 8014


documentation:
  swagger:
    service-list:
    - name: local-swagger
      url: http://localhost:8085/v2/api-docs
      version: 1.0

and my output is as follows,output

could someone help me out by what am i exactly doing wrong here? i am able to get swager ui but it is not showng any list of api's in that. I am new to swagger, so please kindly review my program.

Dilip Krishnan
  • 5,417
  • 3
  • 37
  • 53
mike
  • 395
  • 2
  • 4
  • 15
  • What do you get when you navigate to `http://localhost:8014/swagger-resources`? – Dilip Krishnan Jun 20 '17 at 02:55
  • I cannot see the output because the image link is broken, but did you find a solution? Because I have tried the same, with every microservice in a possible different host and port, and my output is: Failed to load API definition. undefined http://localhost:8070/apihttp://localhost:8081/api – Roman Feb 06 '18 at 14:34
  • Yes I did find solution. But all the services should be on same host and different ports. – mike Feb 12 '18 at 14:50
  • Hey mike, Could you please share your approach? – Akash Chandwani Mar 15 '19 at 17:48

2 Answers2

2

I think there is a CORS ERROR. Please specify the CORS origin header for all of your Swagger documentation services.

For Better Approach: Instead of specifying micro-services URL explicitly. Register all services to Service register and get all your instance details from it. This is the better approach for centralised swagger.

For Reference: Centralized Swagger Documentation

GnanaJeyam
  • 2,780
  • 16
  • 27
2

try this: https://dev.to/eon/how-to-consolidate-api-documentation-in-a-spring-boot-microservices-environment-dgd I was trying to solve this problem earlier, and ended up producing this tool, which is sadly unavailable as open source.

HellishHeat
  • 2,280
  • 4
  • 31
  • 37