How to strategically approach documenting microservices
Every engineering team wants to do the same thing — ship code, fast. In recent years, many companies have been switching over from a monolithic to a microservices architecture approach in order to be able to do just that: build and deploy agile code, with fewer bugs, as soon as possible. But as companies grow and the number of services expands, the same problem often arises: there’s no documentation of what’s been done before, or why.
Because a microservices architecture contains many small, modular service components, each with a narrow scope of responsibilities, keeping track of all of these individual services, their functions, and their data is critical. The code for each service may not be too complex, but the complexity introduced by the large surface area of a microservice architecture can slow down the workflow of even the most productive engineering team.
Building microservices requires planning for every step of the process, from defining the APIs and endpoints to production readiness, but one of the most important — and often overlooked — steps is how you go about documenting microservices.
So, what does it mean to document a microservice as part of a rigorous software development, lifecycle, and what’s the best way to do it?
First: What is a microservices architecture, and why should you consider documenting microservices?
Let’s quickly go over what a microservices architecture is — a modern architecture that's been adopted widely in software development. Many companies, from Google to Amazon to Netflix, are choosing this as a design pattern for their backend web-services due to its flexibility, scalability, ease of continuous delivery, and modular tech stack.
The architectural pattern consists of loosely coupled independent services with bounded contexts, which communicate with other services via an API. APIs are the contracts that allow two services to talk to each other. Common protocols that microservices use are Representational State Transfers (REST) and/or simple messaging such as Java Messaging Service (JMS). They’re often managed and deployed in container environments, like Docker containers on Kubernetes.
Whether you already have a microservices architecture and are trying to optimize it, or if you’re looking to make the switch, you’ll want to carefully consider your approach to every stage of the microservices architecture life cycle.
Today, we’re talking about documentation, which even the most experienced and talented engineering teams can struggle with. Without robust documentation, your entire team’s ability to understand, manage, and maintain the system as a whole is at risk.
As the number of services grows, it's hard to keep track of everything associated with the service (including runbooks, technical specifications, logs, and dashboards). Developers can lose a significant amount of time searching through poorly managed wikis or comments in code.
For a microservices architecture, where services are worked on by different teams, static documentation is crucial to build institutional knowledge for your organization as a whole. Each team could be employing different programming languages, data models, and conventions, so a shared and comprehensive documentation strategy is key.
With proper documentation, you’d be able to easily find each service and its corresponding information without digging through noise. , During active incidents or fires, documentation provides institutional knowledge for the on-call engineer, keeping responses fast and making handoffs easier.
Best practices for microservice documentation
With our work in this space, we’ve seen countless teams’ microservices architecture documentation processes. We’ve seen successes and failures, and what we’ve learned from successful implementation could fill a book. But we’ve condensed our learnings into this blog post, so give these techniques and strategies below a read.
Every organization should approach documentation in a holistic, standard way. Each team deciding its own strategy and guidelines will not work. Specifically, we’ve seen a lot of orgs end up having docs in, say, Confluence’s team spaces, broken down by team rather than service.
Instead, the organization should consider structuring this documentation around services — teams may change, but the documentation will remain the same. You can include a great deal of information in the documentation, including, in metadata, the team working on it and release notes. As the adage goes, make data a first class citizen.
We recommend using a standardized template to structure this documentation, and we’ll get into that more below. We also recommend including endpoint and API information, for example in an OpenAPI spec. API docs can likely be autogenerated, which we’ll also discuss shortly.
Back to the docs themselves: They should be comprehensive, but brief. Ideally, a lot of your documentation should live alongside the code for the service.
In addition, make sure that there is a process in place to update the documentation when relevant changes are made.
You’ll still need a main way to house the docs — developers troubleshooting an issue don’t want to find out the hard way that they don’t have the permissions to view the documentation or are unable to find things when most needed. Options include Github, a wiki, or an internal site, which encourages teams to use documentation and makes information widely discoverable
As mentioned above, in order to standardize your documentation, a best practice is to develop a dynamic template that can be filled in for each new service, and updated for existing services.
Here are some suggestions for the data and metadata that your doc template might include:
- Name: Give each service a unique name. We recommend tailoring the name to the service’s functionality, but teams often have their own naming conventions for their services. Just make sure not to reuse the same name.
- Description: We recommend that you include a brief description of the service’s role, for easier searchability
- Capabilities/Business functionality: which business function the service is built around. For example, if the service is the part of an e-commerce application, if it manages the product catalog, the shopping cart, the check out, the delivery information, etc.
- Service API: define the operations implemented by the service and the domain events published by the service
- Service qualities: also known as non-functional attributes, these are stem attributes such as security, reliability, performance, maintainability, scalability, and usability.
- Observability and monitoring information: this includes health check endpoints, key metrics, logs, and tracing (especially useful if your microservices use REST messaging protocols)
- Implementation: can also include the service’s implementation, such as its domain model.
- Dependencies: the services that the individual microservice relies on and their Service Level Agreements (SLAs).
- Runbooks: information on how to handle each possible alert the microservice can generate (alternatively, this information could be in an FAQ)
- Contact information: what team/who is working on this microservice, and the best way to contact them
- Onboarding guide: if your team is expanding rapidly, it helps to summarize what a new developer working on the service might need to know
- Tags (more on that below)
You can supercharge your docs by by defining your template in a standard parsable format. For example, YAML, JSON, or other structured formats can help you enforce quality of the docs.
Tag, tag, tag
Engineering teams might not necessarily think of it this way, but tagging and good structure are also a key form of documentation. It’s an easy way to look up information for something across all tools.
You can use tags to keep track of everything you and others in your organization are working on. For example, if everything in Datadog uses the same tag, or logs use the same tag, etc., you can search for and find information across larger categories.
As long as your tags are also standardized, as well, you’re good to go.
Integrate 3rd party tools
Don’t forget about the information hosted in 3rd party tools. You should treat all third party tools as documentation, as well, and have standard practices for them, as well.
Automate (what you can)
Feel free to automate documentation as appropriate. That leaves less room for human error. In addition, an open-source tool such as Swagger can help you document and test APIs.
Other automated tools, for example, can even pull live data into documentation.
That’s where Cortex comes in. We can help handle the documentation process. Whether you’re new to microservices architecture, or making sure your existing microservices architecture is running most effectively, you’re going to want your documentation in top shape. Cortex’s automatically updated service catalog gives engineers comprehensive visibility into all services and adjoining documentation. It integrates with the most popular engineering tools, from Azure DevOps to GitLab to Kubernetes to Jira, allowing teams to understand everything about their architecture.
Cortex’s user-friendly dashboard makes documentation and runbooks easy to find, helps teams understand dependencies and SLOs, and identifies owners and on-call rotations. Learn more today.