12

I am trying to generate a single swagger in my microservices project, aggregating all services swaggers into a single one, in the Api Gateway. In order to achieve this, I am following the next tutorial https://objectpartners.com/2017/09/28/aggregate-services-into-a-single-swagger

The problem here is that, when I try to set absolute URLs, the output I am receiving is Failed to load API definition. undefined http://localhost:8070/apihttp://localhost:8081/api/v2/api-docs where localhost:8070/api is the base URL for the api gateway, and localhost:8081/api/v2/api-docs is the docs URL of the swagger of the microservice.

Here is my code:

SwaggerConfiguration

package com.rfd.apigateway.swagger;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
@ConfigurationProperties(prefix = "swagger")
public class SwaggerConfiguration {

    private List<Resource> resources;

    public List<Resource> getResources() {
        return resources;
    }

    public void setResources(List<Resource> resources) {
        this.resources = resources;
    }
}

Resource

package com.rfd.apigateway.swagger;

public class Resource {
    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;
    }
}

DocumentationController

package com.rfd.apigateway.swagger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.List;

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

    private SwaggerConfiguration swaggerConfiguration;

    @Autowired
    public DocumentationController(SwaggerConfiguration swaggerConfiguration){
        this.swaggerConfiguration = swaggerConfiguration;
    }

    @Override
    public List get() {
        List resources = new ArrayList<>();
        for(Resource resource : this.swaggerConfiguration.getResources()){
            resources.add(createSwaggerResource(resource));
        }

        return resources;
    }

    private SwaggerResource createSwaggerResource(Resource resource) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(resource.getName());
        swaggerResource.setUrl(resource.getUrl());
        swaggerResource.setSwaggerVersion(resource.getVersion());
        return swaggerResource;
    }
}

Finally, the application.yml

swagger:
  resources:
    - name: transactions
      url: http://localhost:8081/api/v2/api-docs
      version: 1.0
    - name: payments
      url: http://localhost:8083/api/v2/api-docs
      version: 1.0

And a couple of images that can help to understand the problem:

Api Gateway Swagger URL Api gateway swagger URL

Microservice api-docs URL Microservice api-docs URL

Roman
  • 1,691
  • 4
  • 18
  • 35
  • you have to give url for the docs. what is this `/api` ? – pvpkiran Feb 06 '18 at 21:00
  • The URLs that I'm setting in yml file are the microservices swagger URLs. I have a controller that redirects calls to /swagger-ui.html when asking for base URL (in this case, /api is the prefix for all calls), so basically when you access to localhost:808x/api, you are accessing to the swagger of the microservice. – Roman Feb 07 '18 at 08:28
  • okay. lets step back a bit. The service which is running here http://localhost:8070/api. How do you access swagger ui of this service? – pvpkiran Feb 07 '18 at 08:39
  • I have edited my question thanks to your comment, I wasn't pointing to the api-docs path, but the problem still persists. localhost:8070/api is the api gateway with "api" prefix, and I have a controller that redirects from /api to /api/swagger-ui.html, so accessing to localhost:8070/api, I receive the swagger screen with the error message. – Roman Feb 07 '18 at 08:48
  • Precisely, I was about to say that you are not pointing your url's to api-docs. Good that you figured it out. what error message are you gettting – pvpkiran Feb 07 '18 at 08:51
  • I have updated the question with a couple of images that can help to understand the problem. Thanks pvpkiran – Roman Feb 07 '18 at 08:58
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/164682/discussion-between-darthroman-and-pvpkiran). – Roman Feb 07 '18 at 09:11
  • Actually, it was fixed in 2.9.0 release github.com/springfox/springfox/issues/2372 – Maks Oct 31 '19 at 16:08

3 Answers3

1

The problem here was just the springfox version... I tried to downgrade it from 2.8.0 to 2.7.0 and it worked like a charm. It seems it is a recognized bug, as you can see here: https://github.com/springfox/springfox/issues/2235

I also had to enable cors in microservices but that is another problem.

Roman
  • 1,691
  • 4
  • 18
  • 35
  • Actually, it was fixed in 2.9.0 release https://github.com/springfox/springfox/issues/2372 – Maks Oct 30 '19 at 15:54
0

I was able to solve it by using: https://github.com/varghgeorge/microservices-single-swagger

This simple sprintboot microservice can display all your swagger documentation in one place. Based on YAML configuration, it will display the list of services and provide a single documentation server for all services. In the YAML config, you can add different swagger URLs.

George
  • 81
  • 2
  • 5
0

This issue reappeared in version 3.0.0. And it hasn't been fixed. Everyone is waiting for version 3.0.1. A temporary solution is to download springfox-swagger-ui.jar. There, replace springfox.js. And generate jar again. And then exclude this jar from the main dependency and slip it manually.

implementation("io.springfox:springfox-boot-starter:3.0.0") {
    exclude(group = "io.springfox", module = "springfox-swagger-ui")
}
implementation(files("libs/springfox-swagger-ui-3.0.0.jar"))

Here is a link to a discussion of this issue: https://github.com/springfox/springfox/issues/3413 you will also find a new springfox.js file there