Antora — Microservices Documentation Tool
Documentation? But why?
One of the greatest advantages of microservices architecture is the high autonomy of teams achieved through an independent service lifecycle. A step towards achieving this autonomy often involves breaking down the system into many separate projects, sometimes even hundreds of them. This approach can affect an unexpected aspect, which is documentation creation. The services and libraries we produce constitute a system where building new functionalities based on existing code is commonplace. But how do we know how the code we want to use works? Where should a programmer who is just getting into the project find information about it? Self-documenting code is usually like a unicorn — everyone has heard of it, but no one has seen it. Additionally, there is information that doesn’t fit into Javadoc but is useful. I believe that every project should have at least basic documentation so that one doesn’t have to analyze its content every time. Here, we can use an approach where each microservice or library has documentation stored together with the source code. This way, a developer wanting to update it doesn’t have to leave the IDE. Such an approach promotes documentation creation and updating.
An alternative is to keep documentation on a dedicated wiki page or a tool like Confluence. However, there is a much greater risk here that developers will be less willing to update the documentation, and there’s the potential risk that the external tool will have its problems, such as slow searching. From my own experience, plain text files kept together with the code are more frequently read, written, updated, and after a short syntax learning curve, they pose fewer editing problems. But what about when we want to deliver documentation of the microservices or libraries we create to other teams or clients? What if we want to be able to easily search for information throughout the documentation, regardless of where it is located? What if testers or analysts want to use our documentation, do they need access to the source code then? We can solve the above problems using a tool called Antora, which I would like to present based on how we used this tool in the project I am currently working on.
Act 1, or How to Get Started
The most common approach to documenting projects is to place a README.md file in the project’s main directory. It’s a simple solution, but it doesn’t necessarily work well in a system consisting of a large number of projects. What if we don’t know exactly which project to look for a particular mechanism in?
This is where Antora comes in, allowing us to aggregate documentation from different git projects. After gathering text files from git projects, an output html is generated, which we can host on a server, and even people without access to the code can review the documentation and easily search it.
Get Kamil Lolo’s stories in your inbox
Join Medium for free to get updates from this writer.
To start working with Antora, you need to install Node.js and create a package.json file according to the official documentation. The next step is to create an antora-playbook.yaml file, where we can start configuring the tool. Here’s a slightly more extensive example of such a file than in the official documentation:
sources: # 1
- url: ${GITLAB_URL}/some-repo.git
start_path: docs
...
antora:
extensions: # 2
- './../antora/extensions/maven-version-parser.js'
output: # 3
dir: ./aggregated
destinations:
- provider: fs
clean: false
runtime:
cache_dir: /tmp/antora-cache/ # 4
site:
title: Your application name
start_page: some-project::index.adoc- The sources section contains a list of git repositories to which we can authenticate in many different ways. Each of these projects must have an antora.yaml file with the configuration of the respective project in the directory specified by the start_path field.
- Antora allows creating extensions in JavaScript, which can influence the documentation generation process. In our project, there was a need to correlate the version of the released documentation with the version of the artifact from the pom.xml file. In this case, such a plugin worked perfectly.
- In this section, we can configure where the resulting html file with the documentation should appear. Antora allows you to use either a regular directory, a zip package, or attach your own publishing mechanism implemented in JavaScript.
- In the case of implementing your own plugin that changes the way documentation is generated, it may be useful to specify the directory from which Antora should download the projects specified in the sources section.
- Configuration for the default page, which can come from any project specified in the sources section.
It’s worth noting here that the files in which we store information are not markdown but asciidoc. Both solutions are very similar, however, Asciidoc offers much more than what we can do in a markdown file. This is a slight drawback in the case when we previously used md files and want to move to Antora. We will need to convert the existing documentation to a different syntax and, above all, take a moment to master it.
Customizing Appearance
Customizing Appearance In case we need to customize the appearance of our documentation to corporate standards or client requirements, we can do so by downloading templates, from which Antora generates the resulting html, and modifying selected fragments. After unpacking the files, we need to specify where they are located:
ui:
bundle:
url: ./../antora/ui # 1
supplemental_files: ./../antora/supplemental-ui # 2
antora:
extensions:
- '@antora/lunr-extension' # 3
asciidoc:
attributes:
source-highlighter: highlight.js #4- The directory where we store downloaded templates. We can also store them in the form of a package on a remote server.
- Additional static files used in the generated html, e.g., a Lunr search engine.
- Registration of extensions installed via the npm install xxx command. In this case, it is a documentation search plugin.
- Enabling syntax highlighting, more on that in a moment.
Mając pobrane szablony, możemy dowolnie je modyfikować. Warto tutaj skonfigurować kolorowanie składni fragmentów kodów z wykorzystaniem biblioteki highlightjs. Można to zrobić poprzez dodanie fragmentu szablonu, z którego w wynikowym html pojawi się import skryptu oraz wywołanie funkcji inicjującej mechanizm kolorowania np. w pliku footer-scripts.hbs:
<script src="{{{uiRootPath}}}/js/site.js"></script>
<script src="{{{uiRootPath}}}/js/vendor/highlight.js"></script>
{{#if env.SITE_SEARCH_PROVIDER}}
{{> search-scripts}}
{{/if}}
<script>hljs.highlightAll();</script>Diagrams as a code
A good practice is to create and store diagrams and technical drawings in code form. This makes editing easier, as everyone has a text editor, but not necessarily a tool for editing graphical files. One of the tools that allow creating such diagrams using its own language is PlantUML. Unfortunately, by default, Antora will not be able to render such diagrams. For this purpose, we can use a tool called Kroki, which generates diagrams, supporting various source file formats. This tool is available online, but for security reasons, we should not use this option. Therefore, the simplest solution is to locally run our own server and connect to it. The fastest option is to use a Docker image or a Helm chart to run the Kroki server within our infrastructure. After starting the server, in the antora-playbook.yaml file, we should specify the address of our server:
asciidoc:
extensions:
- asciidoctor-kroki # 1
attributes:
kroki-fetch-diagram: true
kroki-server-url: <URL> #2
kroki-http-method: adaptive
kroki-plantuml-include: https://<URL>/-/raw/master/puml-theme.puml #3
source-language: asciidoc@
table-caption: false- Enabling the extension that supports generating diagrams using the Kroki server. This plugin needs to be installed beforehand.
- Indicating the address at which the server will be available.
- If we want to have globally styled diagrams according to the appearance of our documentation or internal company standards, we can specify the address with the style configuration for PlantUML here.
Having Antora configured, we can create diagrams in code. I recommend an approach where we keep diagram code files in a dedicated directory (Antora enforces its name: partials) and include the diagram in the adoc file content as follows:
[plantuml]
----
include::partial$some-diagram.puml[]
----Thanks to this approach, we will maintain greater clarity of the files and they will be easier to edit.
Building Documentation
Having Antora configured, you can take the final step, which is automating the building and deployment of documentation to the environment. In this case, we used an approach where our pipeline runs a simple script in a Docker image, which initiates the Antora build:
const fs = require('fs');
const fsExtra = require('fs-extra');
const spawn = require('child_process').spawn;
const os = require('os');
const tempDir = os.tmpdir();
const yaml_config = require('node-yaml-config');
const zipper = require('zip-local');
const replace = require('replace');
if (fs.existsSync('target')) {
fsExtra.removeSync('target')
}
fs.mkdirSync('target');
fsExtra.copySync('./antora/playbook', 'target')
const antoraBuildEnv = process.env;
antoraBuildEnv.DOCSEARCH_ENABLED = 'true';
antoraBuildEnv.DOCSEARCH_ENGINE = 'lunr';
antoraBuildEnv.DOCSEARCH_INDEX_VERSION = 'latest';
antoraBuildEnv.FORCE_SHOW_EDIT_PAGE_LINK = 'true';
antoraBuildEnv.CACHE_DIR = tempDir + '/antora-cache/';
# uruchomienie budowania dokumentacji
const npxProcess = spawn('npx',
['antora', '--fetch', '--stacktrace', 'target/antora-playbook.yml'],
{env: antoraBuildEnv}
);
npxProcess.stdout.on('data', data => console.log(data.toString()));
npxProcess.stderr.on('data', data => console.log(data.toString()));
npxProcess.on('error', err => console.log(err.toString()));Here, of course, the building process can be solved in many different ways; this one is optimal for us and allows adding additional necessary steps in our CI process from the script.
Summary
Antora is a very good solution for projects that have distributed documentation and need to ensure a single central point where this documentation is available. It allows easy aggregation of documents and modification of the appearance of the target documentation page. As if that weren’t enough, Antora allows the use of extensions that increase its capabilities. We have many plugins created by the community at our disposal, and if these prove insufficient, we can easily add our own in JavaScript.





