Sep 28, 2017

Aggregate Services into a Single Swagger

By now most companies that have pointed their ship towards some sort of service architecture (in buzz words, microservices) have also discovered an API explorer to ease the pains of developers that are trying to consume services that they know nothing about. Swagger is a popular option when it comes to self-documenting API explorers. In Spring Boot, with a matter of two dependencies and a little configuration you can be running with a “Swagger” endpoint to hit that exposes all available REST endpoints.

This is great, no doubt. However, when you start to expand to more than a handful of services it can become cumbersome to keep track of each service’s Swagger page. Also, depending on how your load balancer is set up it may be hard to target an individual service’s Swagger page from behind the load balancer. For these reasons and a bit of curiosity, I decided to explore aggregating multiple swaggers into their own service. The rest of this post will illustrate how to go about doing this so that you can have a single Swagger that looks something like the image below.

Swagger Aggregate

Swagger service aggregating 4 different services.

Swagger already has support for aggregating multiple service’s API documentation, which they call “resources”. It’s just a matter of knowing where to look and what to override. To get started I stood up a very basic Spring Boot service that includes the normal swagger dependencies (shown below). The snippets throughout the post are pulled from my full project on GitHub, swagger-aggregate.

The only piece that is absolutely necessary to make this work is to create a class that overrides the SwaggerResourcesProvider. It expects an implementation of get() that returns a set of SwaggerResource objects. These point the aggregate to the various Swagger endpoints by providing the service name, url of the api-docs, and the version of Swagger it’s running. In my sample application, I pushed these definitions into the application.yml file and pulled them into a custom object using the @ConfigurationProperties annotation. This is not needed but felt like a good chance to push the configuration out of the code.

To add a new service to the aggregate you simply update the application.yml file with the details of the service’s Swagger. You can define absolute urls pointing to the api-docs or relative if they share the same domain. The example project is pointing directly at the Swagger’s Petstore example docs so that the project actually has some content if you run it.

With services behind a load balancer, it’s possible all of their api-docs might be at the same /v2/api-docs endpoint. If you need to get around this you can customize the api-docs path to be more specific to the service.

The last thing you may notice in the example project is a small redirect endpoint that points /swagger to /swagger-ui.html. It’s always felt unneeded to type that extra ‘-ui.html’, so this fixes that.

Are there ways you’d improve this? Hook it up to service discovery? Enable authentication at the aggregate level?

The source for this project can be found on GitHub.

About the Author

Matt Schroeder profile.

Matt Schroeder

Director, Modern API

A wide range of professional experience and a Master’s Degree in Software Engineering have become the foundation that enables Matt to lead teams to the best solution for every problem.

One thought on “Aggregate Services into a Single Swagger

  1. Roman says:

    First of all, thank you for sharing this post. I am trying to emulate it and you say that we can define absolute urls pointing to the api-docs. However, when I execute it using absolute urls, the output is “Failed to load API definition -> undefined http://localhost:8070/apihttp://localhost:8081/api“, i.e., it is composing the original api gateway URL (http://localhost:8070/api) with the resource url (http://localhost:8081/api) instead of replacing it. Do you know why?

    Best regards.

  2. Ganesh says:

    Can we add custom header like Authorization Header to all aggregated Swaggers?

  3. Declan Treanor says:

    SwaggerServicesConfig: where can I find this?

Leave a Reply

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

Related Blog Posts
AWS Cloud HSM, Docker and NGINX
There is quite a bit of easily searchable content on the security benefits of leveraging a Hardware Security Module to manage cryptographic keys, so I will leave that to the scope of another article. The […]
Google Professional Machine Learning Engineer Exam 2021
Exam Description A Professional Machine Learning Engineer designs, builds, and productionizes ML models to solve business challenges using Google Cloud technologies and knowledge of proven ML models and techniques. The ML Engineer is proficient in all aspects […]
Designing Kubernetes Controllers
There has been some excellent online discussion lately around Kubernetes controllers, highlighted by an excellent Speakerdeck presentation assembled by Tim Hockin. What I’d like to do in this post is explore some of the implications […]
React Server Components
The React Team recently announced new work they are doing on React Server Components, a new way of rendering React components. The goal is to create smaller bundle sizes, speed up render time, and prevent […]