9

w

I have the above architecture in the project. Product, Order, Payment Microservice is a Rest API which currently has swagger integration, but now the flow is changed I can't expose the Microservice Rest API now all the REST API calls is been made from API Gateway.

Is there any way to document the API through API gateway in swagger or what is the best practice for this case.

This is the routing configuration in API Gateway Spring boot

@Bean
    public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/order/**")
                        .filters(f -> f.hystrix(option -> option.setName("order-service").
                                setFallbackUri("forward:/orderFallBack")))
                        .uri("lb://ORDER-SERVICE")
                        .id("order-service"))

                .route(r -> r.path("/payment/**")
                        .filters(f -> f.hystrix(option -> option.setName("payment-service")
                                .setFallbackUri("forward:/paymentFallBack")))
                        .uri("lb://PAYMENT-SERVICE")
                        .id("payment-service"))

                .route(r -> r.path("/product/**")
                        .filters(f -> f.hystrix(option -> option.setName("product-service")
                                .setFallbackUri("forward:/productFallBack")))
                        .uri("lb://PRODUCT-SERVICE")
                        .id("product-service"))
                .build();
    }

Swagger configuration in Order Microservice Project

@Configuration
public class SwaggerConfiguration {
    @Bean
    public Docket orderApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(getApiInfo());
    }

    //create api metadata that goes at the top of the generated page
    private ApiInfo getApiInfo() {
        return new ApiInfoBuilder()
                .title("Fete Bird Order Microservice")
                .version("1.0")
                .description("API for managing Fete Bird Order Microservice.")
                .license("Fete Bird License Version 1.0")
                .build();
    }
}

enter image description here

San Jaisy
  • 15,327
  • 34
  • 171
  • 290

2 Answers2

-1

There is one common practice to make individual swagger endpoints available from gateway itself. I have seen this being done in many production level projects.

For example, for Order service the documentation would be at :

http://gateway-url/order-service/swagger-ui.html

Similar approach could be followed for other micro-services.

  • For the order swagger end point I have http://localhost:8081/swagger-ui/index.html, but I have a filter of .route(r -> r.path("/order/**") .filters(f -> f.hystrix(option -> option.setName("order-service"). setFallbackUri("forward:/orderFallBack"))) .uri("lb://ORDER-SERVICE") .id("order-service")) – San Jaisy Jul 11 '20 at 07:12
  • I have no Idea how to expose swagger UI from Api Gateway, can you please help me with some code – San Jaisy Jul 11 '20 at 07:14
  • Okay, so for that I have a follow-up question. How do you expose your APIs from gateway? – Mubaraka Bharucha Jul 11 '20 at 07:44
  • Yes I can access the API From Gateway API. this one does .route(r -> r.path("/order/**") .filters(f -> f.hystrix(option -> option.setName("order-service"). setFallbackUri("forward:/orderFallBack"))) .uri("lb://ORDER-SERVICE") .id("order-service")) – San Jaisy Jul 11 '20 at 07:45
  • Okay, so unless you have enabled any security on gateway level, you should be able to access swagger using the same url - localhost:8081/order-service/swagger-ui/index.html (Given that gateway is running on port 8081) – Mubaraka Bharucha Jul 11 '20 at 07:49
  • I am getting 404 NOT_FOUND error. 8081 is order service. API gateway port is 8084 when I try http://localhost:8084/order-service/swagger-ui/index.html I get 404.I don't have any security enable. – San Jaisy Jul 11 '20 at 07:54
  • You don't need to do any specific configuration for swagger on gateway, you should be able to access it just as you access any other API. One thing you can do is check out your gateway configuration, it might help if you could post it here. Another thing you can do is make sure you are calling the correct URL for swagger - try localhost:8084/order-service/swagger-ui.html – Mubaraka Bharucha Jul 11 '20 at 08:00
  • No same issue 404. I am able to access the swagger on individual port but not through the API gateway – San Jaisy Jul 11 '20 at 08:07
  • Endpoint gatway is not exposing http://localhost:8084/order/v2/api-docs. Can you help me – San Jaisy Jul 13 '20 at 05:18
  • 1
    Can you help me which one should I used springdoc-openapi or springfox ? – San Jaisy Jul 13 '20 at 06:58
  • I did implement this using spring-fox but I would recommend using open-api as it is the newer version and projects are migrating from spring-fox to open-api – Mubaraka Bharucha Jul 14 '20 at 06:38
  • Please check my answer for Open API configuration – San Jaisy Jul 14 '20 at 06:52
-1

Make sure to have the below dependencies in your services: product, payment, order and api-gateway:

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>${swagger.version}</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>${swagger.version}</version>
    </dependency>

Add @EnableSwagger2 annotation in all of your services.

Add zuul proxy dependencies in your API gateway project. This should route the traffic from api-gateway swagger to your other services.

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>

Add @EnableZuulProxy annotation in api-gateway.

Then, put this config in api-gateway and things should work.

@Primary
@Configuration
public class Swagger2Config implements SwaggerResourcesProvider {

@Autowired
private RouteLocator routeLocator;

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

    routeLocator.getRoutes().forEach(route -> {
        resources.add(swaggerResource(route.getId(), route.getFullPath().replace("**", "v2/api-docs"), "1.0"));
    });

    return resources;
}

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

}

When you will land in your api-gateway swagger page, in the top right you will see a select option for product, payment and order services. Select any of them and try to use the APIs.

Mojtaba Yeganeh
  • 2,788
  • 1
  • 30
  • 49
  • I am not using zuul I am using Swing Gateway – San Jaisy Jul 11 '20 at 07:55
  • Does your swagger works on an individual project? For example, if you land {host}:{port}/order-service/swagger-ui.html, could you make requests? – Artur Yolchyan Jul 11 '20 at 08:08
  • Yes the swagger is working in the individual project. But not from the API Gateway – San Jaisy Jul 11 '20 at 08:11
  • So, the problem is with proxying the requests. What is Swing Gateway? I couldn't find any maven dependency for it to test locally. Is it some custom-developed library or something which we can find in maven central repository – Artur Yolchyan Jul 11 '20 at 08:35
  • Sorry my typo mistake it us Spring Gate way https://spring.io/projects/spring-cloud-gateway – San Jaisy Jul 11 '20 at 09:00
  • Any luck ? I am not able to get the doc v2/api-docs from the gateway API – San Jaisy Jul 12 '20 at 18:16
  • I followed your instruction I am able to get the swagger ul in the API gateway, but the not able to get the swagger doc as you can see in the example. My end point is not exposing http://localhost:8084/order/v2/api-docs – San Jaisy Jul 13 '20 at 05:18
  • Is it because I am using implementation "io.springfox:springfox-boot-starter:3.0.0-SNAPSHOT" this ? – San Jaisy Jul 13 '20 at 06:08
  • Can you help me which one should I used springdoc-openapi or springfox? – San Jaisy Jul 13 '20 at 06:58