July 28, 2015 | Microservices
Recently I co-presented a talk at Goto Amsterdam on lessons learnt whilst developing with a Microservices architecture; one being the importance of defining and documenting your API contracts as early as possible in the development cycle. During the talk I mentioned a few API documentation tools that I’d used and, based on feedback and questions from attendees, I realised that this topic merited a blog post. So, the purpose of this is to introduce 5 tools which help with designing, testing and documenting APIs.
WRITTEN BY
I’ve spent the last few months leading a team developing a Microservices application using the Spring Boot framework, so all tools will be discussed in the context of their support for Spring Boot, however, only 2 of the tools are purely for Spring, the other 3 support a range of languages and frameworks.
For each of the above I used an example Spring Boot Rest service application to demonstrate how it documents the API contracts, what the resulting documentation looks like and provide insight on when it might be appropriate to use. The example app exposes a set of CRUD APIs for storing details about books (apologies for lack of originality) and it can be downloaded/cloned from this Git repo: https://github.com/cyberbliss/springboot-rest-example
.
To run it requires you to have Java and Maven installed (I’ve tested using Java 8 and Maven 3.2). Once you have cloned/downloaded the source, use this command from your CLI to run the application:
mvn spring-boot:run
Once started you can access the APIs on localhost:9080, e.g.
http://localhost:9080/api/books
This tool is probably the most well-known of them all for documenting Rest APIs – its basically a REST API ecosystem consisting of several aspects:
I’ve used Swagger with a Java library called Springfox (http://springfox.github.io/springfox/docs/current/) which is designed to generate a Swagger spec from APIs built using the Spring framework. It does this by recognising the Spring REST annotations and converting these to the appropriate Swagger spec elements and then exposing an endpoint which, when called, returns the spec in json format. Springfox also supports the Swagger annotations (@Api, @ApiOperation etc) which enables you to provide additional details, e.g. descriptions.
The instructions below summarise how to integrate Springfox with a Spring Boot app and there is a working version in my example app:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.0.2</version>
</dependency>
SwaggerConfig
class (there is an example in the example Books application)path/to/swagger-ui/dist/index.html
in your browsermvn spring-boot:run
dist/index.html
in your browserhttp://localhost:9080/v2/api-docs
. Paste it into the field at the top of the Swagger UI page and hit Enter; you should then see something similar to the screenshot below:It is fairly straight-forward to integrate Springfox into Spring and clearly a major benefit is that there is no requirement to write anything extra as Springfox uses the Spring REST annotations already present in your code. Of course, the downside to this is that you have to have written the code first, or at least enough to include all the annotations. Another downside is that in order for Swagger UI to pick up the API spec the Spring application has to be running in order that the endpoint is available.
An alternative to Springfox (which I haven’t tried) is a Swagger Maven plugin (http://kongchen.github.io/swagger-maven-plugin/) which scans the Spring app for Swagger annotations and writes to a file the generated Swagger spec – this could be configured to run at build time, for example. Unfortunately this plugin doesn’t recognise Spring’s REST annotations.
Sadly, the current Swagger spec (v2.0) has no support for HATEOAS and there doesn’t seem much intent to do so in the future.
This is an official Spring project, the aim of which is to assist with the production of REST API documentation by hooking into the Spring MVC Test library. The idea is you write a test for each resource which describes the expected request and response and, if the actual matches the expected then documentation will be generated in Asciidoctor format. The deliberate consequence of this is that the API documentation will match reality. The project also provides the ability to manually add further documentation and supports HATEOAS (with out of the box support for Atom and HAL formats).
Integrating with Spring was straight-forward and the documentation is helpful. The instructions below summarise how to integrate Spring REST Docs with a Spring Boot app and there is a working version in my example app:
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs</artifactId>
<version>1.0.0.M1</version>
<scope>test</scope>
</dependency>
<snippetsDirectory>
${project.build.directory}/generated-ascii-doc
</snippetsDirectory>
SpringRestDocsAPIDocumentationTest
, in the Books application. Running the tests in this class will not only test the API contracts but also, if they pass, write the various details about the APIs (request, response, fields etc) to Asciidoc format files in the previously specified snippets directory.src/main/asciidoc
target/generated-html-docs/api-documentation.html
An example of the documentation produced is shown below:
RAML (RESTful API Modelling Language) provides a yaml based specification for describing REST APIs. On GitHub there are many projects providing tools for use with RAML: parsers for various languages, e.g. Java, Python, Javascript, Ruby; UIs to help write your API spec; documentation generators and libraries to help test whether an API implementation matches its RAML definition.
Despite being a fan of yaml I discovered that using it to describe APIs was not at all fun; akin to handcrafting a SOAP WSDL (for those old enough to remember). Fortunately there are a few tools to help reduce the pain, e.g. a syntax highlighter for Sublime and API Designer which is a browser based editor to help write the yaml. The RAML spec file which describes the Book APIs can be found in src/main/resources/api.yaml in the example app.
This screenshot shows a fragment of the yaml within the API Designer tool:
There are a few projects on GitHub for converting a RAML spec into human readable documentation, unfortunately none support Asciidoc. Instead I used raml2html – a command line tool which produces HTML – the resulting web page looks like this:
There is no support in the current RAML spec for HATEOAS, although, judging by the comments in their forum, it is on the radar for a future release.
In the course of my investigations I came across a couple of other tools that, whilst nowhere near as feature-rich as the previous 3 are still worthy of mention.
This tool is written as an NPM module (so you’ll need Node installed to use it) and supports a wide number of languages including Java, Go, C++, Ruby, PHP and Python. Essentially you document your APIs using pseudo annotations within a comment block in your code – the tool then parses these comment blocks and generates some static web pages containing the actual documentation.
The following is an example of using the pseudo annotations:
/**
* @api {get} /api/book/:isbn Get a book via its ISBN code
* @apiName getBookByIsbn
* @apiGroup Books
*
* @apiParam {String} isbn The book's unique ISBN code
*
* @apiSampleRequest http://localhost:8095/api/book/111-1
*
* @apiSuccess {String} isbn Book's ISBN
* @apiSuccess {String} title Title of book
* @apiSuccess {String} author Book's author
* @apiSuccessExample {json} Success-Response:
* HTTP/1.1 200 OK
* {
"isbn": "111-1",
"title": "Java 8 Lamdas",
"author": "Richard Warburton"
}
*
*/
As I create an Interface class for each of my Spring Rest Controllers, I found putting the ApiDocJS style comments in the Interface effective and it was straightforward to include Maven tasks in the application’s pom to call the tool and publish the generated artefacts to an nginx server.
ApiDocJS has a very small learning curve, generates clean, modern looking web pages and its usage documentation is clear. I also like the fact that the documentation is close to the code and that you can write it without having first written any code (I don’t count creating an empty Interface as writing code). However, the obvious downside to this tool is that the quality of the documentation will only be as good as the quality of the comments manually entered by the developers; so, if your developers are not diligent about keeping the comments updated when the APIs are changed the documentation will quickly become useless. The tool makes no effort to generate example requests and responses so the onus is on the developer to provide these using the annotations: @apiParamExample and @apiSuccessExample – one annoyance is that no pretty print style formatting is done on the supplied json, so you have to do the indenting manually.
There is nothing in the tool to inherently support HATEOAS, so you would need to use the @apiSuccessExample annotation to provide an example.
To generate the documentation via the command line use this Maven command:
mvn exec:exec
This generates all the necessary html, css, javascript within the ./target/apidocs directory
– to view it in your browser load ./target/apidocs/index.html
As its name suggests this is a tool specifically aimed at Spring; like Springfox it is Spring REST annotation aware and will generate API documentation, in Asciidoctor format, for any class annotated with @RestController. It takes advantage of Spring’s support for MockMVC and so execution requires creating a mock (pun intended) test which essentially interrogates the Spring MVC RequestMappingHandlerMapping object for details of the REST API methods and outputs the result in json or AsciiDoc format.
The instructions below summarise how to integrate SpringRestDoc with a Spring Boot app and there is a working version in the example Books app:
<dependency>
<groupId>nl.tritales.springrestdoc</groupId>
<artifactId>springrestdoc</artifactId>
<version>0.1.0</version>
<scope>test</scope>
</dependency>
SpringRestDocAPIDocumentationTest
, in the Books application. Run this class and it will create a target/generated-ascii-doc/spring-restdoc.asciidoc
file.mvn asciidoctor:process-asciidoc
This will generate an HTML file in target/generated-ascii-doc.This project is in its early stages and is the product of one developer. The documentation produced is minimal, too much so to be particularly useful. Hopefully this will change with future releases.
Out of the 5 rest API tools I’ve investigated there are 3 which I would seriously consider next time I need to document some APIs: Swagger, Spring Rest Docs and RAML and in the table below I’ve summarised why and when you might choose one instead of another.
This blog is written exclusively by the OpenCredo team. We do not accept external contributions.
Rest API tooling review | Swagger | Spring Rest Docs | RAML |
Best used for | Both top-down (contract first) and bottom up (code first) design | Ensuring that your API documentation accurately reflects your Spring REST API implementation | Contract first design |
Language support | Documenting an API contract is language neutral, but there is tooling for: Javascript, Java, Clojure, Go, .Net, Perl, PHP, Python, Ruby | Java (Spring MVC) | Documenting an API contract is language neutral, but there is tooling for: Java, Javascript, .Net, PHP, Python, Ruby |
Hypermedia support | No | Yes | No |
Build phase integration | Yes, via Maven plugins | Straightforward with Maven or Gradle | To a degree – there are some CLI tools to convert spec to documentation |
Related GitHub projects | approx. 1300 | N/A | approx. 400 |