In organisations that produce SaaS products with public APIs, there is sometimes complex interplay between who is responsible for what ultimately becomes public-facing API documentation. At MessageMedia, some of our APIs have had multiple developers involved in the creation of the documentation before it becomes public-facing, at which point the Developer Relations team is responsible for making it ready for your consumption. We also have APIs that are used internally as well as externally. Keeping our public-facing documentation up to date is something we’re working on improving at MessageMedia.
API Blueprint is a high-level API description language. It’s an alternative to OpenAPI specifications (also known as Swagger). API Blueprint can be preferable in some circumstances because it is known for being easier to read for members of the team who don’t spend all day ‘down in the weeds’ of the code. An .apib file is essentially a markdown format file and its look and feel is familiar to anyone who has edited a Github readme file before. It’s easy for a community manager or a product manager to change a description or add things with confidence that they’re not going to ‘break’ the way something renders. Some of the disadvantages of using .apib are that it lacks the same ecosystem around code level tooling that Swagger has. For example, Swagger code-gen is a huge time-saver for generating SDKs directly from a Swagger specification. I’m in the process of working around this but for now, we’re ‘all in’ on API Blueprint at MessageMedia.
Including markdown templates
Aglio is an API Blueprint renderer that outputs static HTML, similar to Swagger UI for Swagger specs, or any of the other OpenAPI spec renderers. Aglio has several benefits for .apib users, including multiple themes and customisable output. However, the feature that really appealed to us, in this case, was the ability use ‘includes’. An ‘include’ is a separate markdown document nested in your API spec project that can be “pulled in” to the final render, and used in other neighbouring renders. This means that we can, for example, include the main body of the reporting documentation from the reporting team, include another team’s authentication information, and include any other surrounding information like a Postman collection button. In this scenario, Aglio will spit out a complete public-facing .abib file.
Distributing across teams
Now that we understand the concept of how Aglio can generate from multiple sources, the second issue is how to get sources from multiple git repos in the right place. The reporting team has its, Developer Relations has a public-facing documentation repo, and we need to be able to reference the master version of their repo so that changes get pulled in as they occur. The answer to this problem is submodules.
Sub moduling is a git feature that allows you to use another project from within your project. It’s similar to including a package via a package manager. You can read more about the feature and its usage here, but to get started quickly, follow these instructions:
Step 1: Add the submodule
git submodule add git://github.com/coder_bec/docsmaster.git docs
Step 2: Fix the submodule to a particular branch (devrel branch)
git checkout -b dev_branch origin/dev_branch
Step 3: Commit everything
git add . git commit -m 'adding submodules'
Now, whenever the reporting team does an update to their repo, they do a PR to our branch – can we add this as a pipeline? – maybe.
Now when a change is made to a downstream submodule, you fetch and merge it.
Step 4: Fetch and merge
git fetch git merge origin/master
The question then becomes how to make sure you know when to fetch and merge and push your new docs. For now, we have a notification on the bitbucket repo that tells us when to do this. In the future we could look at ways to automate this. Let us know on our Developer Slack if you have any suggestions!
Putting it all together with Buildkite
Now that we’ve got our new process and it’s pulling in from all the right places, we can make a Buildkite pipeline that does a bunch of stuff and deploys our .apib file to our Apiary account.
In the pipeline file above, we lint the documentation, validate it with a file that checks it’s a proper .apid file, then publish it to our Apiary account.
In the future, we will look at using the HTML rendering features of Aglio and moving outside of Apiary. We may also be looking at ways to automate this process. I’m going to share a bigger version of this as a talk, with a demonstration and sample repo, at APIdays Melbourne on September 19th. Get your tickets here: https://www.apidays.co/melbourne