Revolutionizing API Documentation: A Journey from Micro-services to Centralized Contracts

Rajesh Gupta
Deutsche Telekom Digital Labs
4 min readOct 13, 2023

--

Problem Statement

In micro-services architecture, every micro-service offers specific capabilities to the client. If a client intends to integrate with the application, it must be aware of the API contracts.

We wanted to explore How can API contracts be shared with our clients?

As a first step, we realise that there are two possible approaches —

  1. Generate API contracts for each service/API, store them in a shared location, and provide the location to clients.
  2. Utilize an API documentation tool that retrieves API contracts directly from the micro-services and presents them to clients.

The first approach requires manual intervention to generate and update API contracts. However, the second approach is more automated, as contracts are generated by the application itself at runtime and served to clients.

We move on to the next problem — How can the system automatically generate these contracts?

Several libraries, such as the springdoc-openui library for Java and the Spring project, offer the capability to read code and generate API contracts. These libraries often provide a user interface (UI) for viewing the contracts. By incorporating these libraries into each micro-service, the contracts can be obtained.

However, this approach introduced a new challenge for us:

Will clients be willing to use multiple URLs (different URLs for different services/APIs) to access contracts?

The answer was a resounding “NO.” Clients prefer a single URL from which they can fetch all API contracts. This realization called for us to create a Centralized API Documentation tool.

Learn below on how we created a Centralized API Documentation tool.

High Level Architecture

  1. The open-api-client is integrated into every micro-service and handles the generation of API contracts, which can be accessed via the following URL: “http://{micro-service base URL}/v3/api-docs.”
  2. The open-api-server acts as a central component that communicates with all micro-services within the system. It retrieves API contracts from the micro-services and stores them in a persistence layer.
  3. Redoc serves as a UI component responsible for rendering API contracts in a web browser. It interacts with the open-api-server to retrieve the persisted API contracts.

Why do we prefer this over the manual approach?

  1. We can create a centralized location where all API contracts can be found.
  2. Since the API contracts are fetched directly from the running applications, any modifications made to the contracts will automatically be reflected once the changes are deployed
  3. No manual interventions are needed, saving man hours and human dependence.

Here are the external resources we needed to use to solve for this-

  1. open-api-client -
    a. swagger-annotations — The library offers annotations that can be incorporated into code in order to generate documentation.
    https://github.com/swagger-api/swagger-core/tree/master/modules/swagger-annotations
    b. springdoc-openapi — By reading the annotations of the swagger-annotations library in your code, it generates API documentation.
  2. open-api-server — Similar to any other Spring Boot application, it can communicate with a service registry (such as Eureka, K8 service discovery, or any other registry) and retrieve information about all the services operating within the ecosystem.
  3. Redochttps://github.com/Redocly/redoc

Our next course of action -

We will develop two Spring Boot applications: one that exposes specific functionalities, and another one that acts as the open-api-server. Additionally, we will require a client-side application to render the API contracts.

  1. API contracts producer

a. Add below dependencies in pom.xml

b. We will then create a TestController class that exposes a REST endpoint and include the necessary swagger-annotations —

After starting the application, if we access the endpoint http://{micro-service base URL}/v3/api-docs, we can receive a response similar to the following:

2. Open-API-Server

This upcoming Spring Boot application will dynamically gather contracts from operational services, merge them, and then securely save the combined contracts. Upon a client’s request, it will promptly fetch these aggregated contracts from the persistence layer and promptly deliver them as a response.

3. Client-side application

We have the flexibility to develop a client-side application using Angular or React.js. To achieve this, we need to include the Redoc library and specify the backend API path that returns the aggregated contracts from all services.

Once we start both the Spring Boot and client applications and access them through a browser, we should be able to visualize a user interface (UI) similar to the following:

To further enhance this tool, we can consider adding the below features for support:

  1. To address the visibility of internal and external REST APIs in each application, we can implement Role-Based Access Control (RBAC). This allows us to determine which APIs should be accessible to specific users based on their roles.
  2. At times, clients express interest in generating client-side code using the Swagger file. In response to this, we can offer them the option to download the Swagger file for specific resources directly from the UI.
  3. To accommodate changes in API contracts over time, it is important to incorporate support for versioning. Users should have the ability to view all available versions of a particular API and download the corresponding API contract.

Happy Learning, Happy coding!

--

--