A Comparison of REST Documentation Frameworks in the Java Ecosphere
Considering which Java framework to choose from to document your REST APIs can be quite the hassle. In this blogpost we will therefore briefly compare the three documentation frameworks for REST web services that are used within Foreach, and how they integrate with the Spring framework (which is the Java framework most often used at Foreach). These are RESTful API Modeling Language (RAML), Swagger UI and Spring REST Docs.
In each part we will give a high-level overview of the documentation framework discussed. We will briefly describe how the documentation framework is integrated with Spring and how using the framework for your documentation affects the build cycle.
RESTful API Modeling Language (RAML)
RAML is a separate document that is kept alongside the project that you, as a developer, need to maintain manually. In the default RAML configuration, almost nothing is done automatically. However, with the plugin ecosystem that comes with it, it’s quite easy to extend RAML to behave the way you want it to.
This documentation framework’s ecosystem is very active, with plugins that enable various functionalities, such as:
- API Workbench: A "rich, full-featured integrated development environment (IDE) for designing, building, testing, documenting and sharing RESTful HTTP APIs";
- RAML Java Client Generator: A tool that automatically generates Java clients based on RAML documentation;
- RAML2HTML: A Node.js tool used to generate a user-friendly HTML document.
The written documentation is converted from the RAML format to human readable text (or HTML) during an extra step defined in the build process.
In the past, RAML used to be our preferred documentation framework within Java, but now that we have discovered some of the alternatives, we have started using RAML less and less. Also, with RAML it is a bit harder to write complete documentation that is also user-friendly (since all documentation in RAML needs to be written manually). Furthermore, we had a general tendency to forget to update the documentation after making adjustments to the API; an issue that can be solved by using a framework in which most API changes are documented automatically rather than manually.
In contrast, Swagger UI generates everything automatically. In this framework, Swagger works in tandem with Swagger UI and Springfox to generate documentation at runtime. This framework actually consists of three components:
- Swagger is the specification part: A set of rules for describing RESTful services (this is comparable to RAML);
- Swagger UI is the rendering part: It renders user-friendly HTML (like RAML2HTML does) and allows users to test the service without having any client infrastructure in place, as it automatically generates a test client based on the Swagger specification of the service;
- Springfox is the “generating” part: It interacts with the service (via annotations, both its own and Spring annotations) to automatically generate the documentation at runtime.
Those three look at your code to determine what needs to be documented; they generate both the documentation (via a dynamic website) and the possibility to do "test service calls" via the Swagger UI. The service calls work the same as, for example, Postman, with the only difference that this library can work in the browser, namely by sending raw requests to the service from the documented part of your application.
Since Springfox will take care of the generation at runtime, there is no need to define extra build steps (unlike RAML and Spring REST Docs, in which a separate build step is necessary).
When we first started using it, the Swagger stack seemed to be awesome. We barely had any (manual) labour, because everything is generated automatically. At the same time we were still able to adjust the documentation a bit by adding annotations to our code. In our opinion, this is both a strength as well as a weakness. Because although Swagger UI is indeed easy to use, we did not have as much control over the generated documentation as we would have liked.
Spring REST Docs
Spring REST Docs is a part of the Spring ecosphere that generates AsciiDoc snippets based on your unit tests. These snippets can be included in hand-written AsciiDoc to assemble documentation for your API.
To do this, you specify which fields you expect to retrieve from a call to a MockMVC-endpoint and you define where you want to create the generated snippets on your file system. If the expected fields do not precisely line up with the results, your tests will fail, which means that the documentation related unit tests also serve as an extra sanity check for your code.
Later in the build process you will need to define an extra step that generates a human-readable HTML file by combining the generated snippets with the hand-written index pages; thus facilitating the spread of the documentation.
We used Spring REST Docs in a project that required a combination of API and regular documentation for an external party. They were using their own test tools, so it was not desirable to provide them with a browser-based interface to test the interface. We picked the REST Docs framework because (a) it could also be a part of our integration tests and (b) we could easily combine it with all our other, non-technical, documentation.
As can be derived from the previous comparison, everything depends on what you expect your documentation framework to be able to do. Out of the box it is easier to use Swagger UI if you expect you won’t need a lot of “static” documentation (i.e. if everything can be autogenerated).
On the other hand, if you need to be able to provide a singular piece of documentation, or if you just want more control over your documentation, you might be better of using the likes of RAML or Spring REST Docs. Also, the integration with tests in Spring REST Docs has already proven to be very useful.
Whatever you choose, every single framework is sufficient to communicate the contract of the web service to other developers in an unambiguous manner - which is ultimately the goal of these frameworks.