Automate Documentation for Microservices — Continuous Delivery

Varesh Tapadia
5 min readMay 21, 2019

Enterprises with Microservices Architecture and DevOps/Scrum culture, normally had a tendency to assume that the documentation is not useful. Most of the time, we have seen documents that are out of sync with what is implemented in reality. The whole process of keeping documents updated is seen as a legacy approach and more and more developers are not keen to do it.

However, when a new developer/tester joins a team, the first thing he/she ask is if there is any documentation. For this sole reason alone, I think it is important to maintain information in a more formal way then looking into code and reading the Java Docs. Here, I present some solutions to how we can automate the documentation for a project, which not only helps in speeding up the whole process but also provide insightful information about the project and team.

Note: The below solutions were tried with Spring Boot based Microservices but the principles could be replicated in any other framework and language. The main aim was to make documentation easy.

Open API/ Swagger

Open API is a standard way of documenting all the public interfaces the application exposes to the outside world. While defining the guidelines for the Microservices architecture, we decided that all applications should expose there API using the Open API specification. Our aim was to ensure that this does not add any additional burden to the developer.

We achieved this via the SpringFox dependencies. Some of the most common ones that we use are listed below with there uses.

<!-- Provides a Swagger UI with the application, makes live easy to do a quick test of the service -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox.version}</version>
</dependency>
<!-- Main dependency to enable swagger/openAPI v2 specs-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox.version}</version>
</dependency>
<!-- Parsing the Javax Validation -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>${springfox.version}</version>
</dependency>
<!-- Processing API defined using Jax-RS specs -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- Parsing the Hibernate Validation Annotations -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-hibernate-validations</artifactId>
<version>${swagger.version}</version>
</dependency>

With this in place, we used to define a simple SwaggerConfig class that is normally copied by all the developers from one project to another. A sample file is shown below.

@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Autowired
private Project project;

@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
//Used to define the API URL path which needs to be added to the project
.paths(PathSelectors.regex("/api/.*"))
.build()
.pathMapping("/")
.apiInfo(apiInfo())
.genericModelSubstitutes(ResponseEntity.class)
.useDefaultResponseMessages(false);
}

private ApiInfo apiInfo() {
return new ApiInfo(
project.getName(),
project.getDescription(),
project.getVersion(),
null,null,null,null,
Collections.<VendorExtension>emptyList());
}
}

This configuration class, uses a Project bean that is defined as below.

@Component
@Data
@ConfigurationProperties(prefix = "project")
public class Project {
private String name;
private String description;
private String version;
}

The values for this bean is retrieved from the maven project using the following settings.

project:
name: '@project.artifactId@'
description
: '@project.description@'
version
: '@project.version@'

As can be seen, all of these can be copy pasted and will work in all the projects and give developers a quick start. At the end, all projects extend and improve the documentation based on there project, but a good start really makes life a lot more easier.

Maven Site

One of the most useful feature of maven I like is the mvn site goal. I have exploited this feature for so many use cases that I think all teams should follow this approach. We use maven for our application build and release process and every time, we used to release a new version of the application, SDD, TER and all other documents were requested by the Release and Change Process. Maven site can help in creating the first version of these documentation and help team not been bothered by the process. There is the added benefit that since the documentation is generated by the code itself, it is always right and correct.

To configure this, you need to have a site location that can be used to host static files. As an example, nexus OSS comes with a site repo that can you configure/create. This can be used to upload and serve static content. In the distributionManagement section of your pom, you can add the site related details and the URL where the project will be uploaded.

<site>
<id>nexusSite</id>
<url>${site.repo.url}/${project.artifactId}/${project.version}</url>
</site>

Here the nexusSite is an id to the server settings that can be configured in the maven settings.xml at the single place. Adding version ensured that the documentation is updated and released everytime a new project is released.

Report Plugin examples

Here are some of the reports plugin (These plugins are defined under the <reporting> tag and not under the <build> tag) that I have used and how to configure them.

Maven Project Info Report plugin the default plugin used by everyone. There is a bunch of reports that you can configure. I normally use the ones listed below but its pretty useful to extract useful information from the pom.xml

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>${maven-project-info-reports-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>index</report>
<report>summary</report>
<report>license</report>
<report>issue-tracking</report>
<report>project-team</report>
<report>scm</report>
<report>cim</report>
<report>dependencies</report>
<report>dependency-convergence</report>
<report>plugins</report>
</reports>
</reportSet>
</reportSets>
</plugin>

Maven Javadoc Plugin is another one of my preferred one. This takes the Javadoc written by developers and generates the normal API documentation. This is easy to read by developers when the code is not accessible and if they don’t want to checkout the code locally.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<!-- Use it to disable the doclint checking. -->
<additionalOptions>-Xdoclint:none</additionalOptions>
</configuration>
<reportSets>
<reportSet>
<reports>
<report>javadoc</report>
<report>test-javadoc</report>
</reports>
</reportSet>
<reportSet>
<id>aggregate</id>
<inherited>false</inherited>
<reports>
<report>aggregate</report>
</reports>
</reportSet>
</reportSets>
</plugin>

Another useful plugin is the Maven Change log Plugin. This plugin provides which developers have been working in the project or what files have been modified. It’s useful information to managers also :).

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-changelog-plugin</artifactId>
<version>${maven-changelog-plugin.version}</version>
</plugin>

Another plugin that we use is the Maven Surefire Report Plugin. This plugin parses the test results and generates a pretty HTML report. With integrated test running using the Cucumber framework, this report can be used as a automated report for the test execution.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>${maven-surefire-report-plugin.version}</version>
</plugin>

Security is very important and if your organization requires OWASP related vulnerability scan, this is a very good candidate. The plugin provided by owasp team, can be used to fail the build in case of known vulnerability found. But it can also be used to generate report from the project code base.

<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>${dependency-check-maven.version}</version>
<configuration>
<skipProvidedScope>true</skipProvidedScope>
<skipRuntimeScope>true</skipRuntimeScope>
</configuration>
<reportSets>
<reportSet>
<reports>
<report>aggregate</report>
</reports>
</reportSet>
</reportSets>
</plugin>

Git Markdown

All the above documentation are used by the management, but developers like to checkout the code and try to figure out what needs to be changed. Markdown is a great language in documenting and fits perfectly into this. Functional documentation can be made part of the project documentation itself and document updates can be reviewed in the same way as code (git Merge Requests).

This way of documenting within projects is the best possible place for teams to maintain it. There are additional smart utilities (like MermaidJS) that can help in improving this experience even further with sequence diagram and Graphs.

--

--