Tips for writing great API documentation

Documentation is an important part in the Software Development Life Cycle(SDLC) though frequently disregarded by developers who are either uninterested in placing proper docs or rushed by upper management, deadlines or clients who wanted their software done by yesterday.

As many things in software, documenting code can be practiced and become used to it gradually. In this article we’ll share some easy-to-follow steps to document your code without adding more burden to devs daily workload.

Documenting software would be seen as a tedious process two decades ago, mainly, because most software needed to be installed in end users machines. This meant things like user manuals and similar documents were required to help them install and use it.

We live in the days of Internet, those manuals are(might be) no longer required but we still need to document our code. Modern days software users might not need to read a manual but other kind of users(fellow developers) would be done a favor if we document our functions, classes, modules, APIs, etc. The format changed and now we shouldn’t care about writing a paper-like document but rather provide it in the form of comments, API docs(like Stripe’s), READMEs, and so on.

Fortunately, there are several tools(Slate, Read the Docs, Aglio) that make documenting easier than ever, many of them can generate web pages by just following a given format or syntax. There are ones specific per language like Ruby’s Yard, PHP’s Documentor, JS Doc for JavaScript which leverage the use of comments to generate good looking web pages that describe your classes behaviors, functions arguments, and more.

It’s nice to have the tools at our disposition but is unclear how to properly use them. We’ll try to provide some good advice on how to do it.

Ways to Properly Document your Project

Let’s focus in three different aspects of the process. Bear in mind these work well for either REST APIs(e.g., the ones provided by third parties) or library APIs(e.g., describe how to use a library, gem, module, etc):

  • General instructions: README, entity diagrams, specific flows.
  • General documentation: for functions, classes, modules, REST API reference pages, etc.
  • Specific documentation: way too specific code that will benefit from more mundane comments.

General Instructions
Refers to documentation that describe different aspects of a software project. It could be a detailed README.md file with specifics about the project:

  • Software dependencies: every software the project needs to work.
  • Development setup: how to start a development environment, Do I run vagrant up or docker-compose up?
  • Defined git flow: long-live feature branches or trunk-based development?
  • Folder structure: Is there a predefined folder architecture to give order to the project files?
  • How to use the library: examples of how to use the classes your library provides.
  • Required environment variables: AWS_SECRET_KEY_ID and friends are necessary?

Another way to provide general instructions kind of documentation is placing diagrams of entities, e.g., entity-relationship diagram, deployment workflow, third party integration workflow, just to mention some.

To create a good README you can refer to The Art of README to learn a few key points. Also, good examples of the points mentioned before are the READMEs of libraries used by Ruby on Rails. See how detailed is the README for gem ActiveModel or ActionMailer.

Be mindful they’re just examples. Do whatever fits best to your project’s README. See Etsy’s Immutable Documentation experiment to get in idea of doing the process but in a completely different way.

General Documentation
Here we start documenting our code. The best way is to use a tool that would provide a syntax or format(this promotes consistent documentation across the project) and also because they usually generate an HTML page without further work from our side.

In the case of the Ruby programming language, RDoc and YARD are two popular gems to generate docs. The docs of Ruby and Ruby on Rails are written in RDoc format.

A good example is the docs of the ActiveRecord::Relation#find_or_create_by visible in GitHub:

# Finds the first record with the given attributes, or creates a record
# with the attributes if one is not found:
#
# # Find the first user named "Penélope" or create a new one.
# User.find_or_create_by(first_name: 'Penélope')
# # => #
#
# # Find the first user named "Penélope" or create a new one.
# # We already have one so the existing record will be returned.
# User.find_or_create_by(first_name: 'Penélope')
# # => #
# (...)
#
# If this might be a problem for your application, please see #create_or_find_by.
def find_or_create_by(attributes, &block)
find_by(attributes) || create(attributes, &block)
end

Of course we do not have to make docs as precise and perfectly written but the idea is to provide as much detail as we can. Notice how the method definition is explained with usage examples.

What about documentation if we are building REST APIs? There are also good tools for that.
Slate, Read the Docs, API Blueprint, Postman, or Docusaurus are really good ones.

The only caveat to using such mentioned tools is that you’d need to write all the specifics. They do not generate docs web pages out of code, you’d rather have to write the documentation, following a format or syntax they can read and build HTML sites from.

In that sense, Postman is very convenient as it saves you a lot of typing with a click of a button with its examples feature.

For REST APIs documentation, you’d normally want to have the following:

  • Endpoint description: what it does and what it does not.
  • Attributes that could be send in the request: Is it an integer or a string? Is it required? Is an object or a collection?
  • Example of a request body: a JSON example of the request body with all possible attributes.
  • Example of a request response: a JSON example of the response body with all possible attributes.
  • Possible HTTP status codes in the response: Is it a 200? 500? 404?
  • Meaning of each status code in the context of the API your building: Some API decide that 201 is for created or patched. You can also define and give a singular meaning to each of them(not recommended, though).
  • Request headers that could and/or have to be sent: for authentication, e.g., you could send the Token header.

What’s important here is to provide our API users with all the information we can and all the information they could need to work with our REST API.

An autogenerated web page is a head start to help them reach the goal of working with you. That’s why we see beautiful, eye-catching API references sites like Stripe’s, Spotify’s, and Google Places to mention some.

Specific Documentation
In this category falls everything that might not be covered by a tool or a process of documentation. All those things that to other colleague would seem unnecessary, redundant, or even removable, with a comment explaining why they exist(in plain english) would help them, even your future self, understand the reason that piece of code is there.

The focus of this comments should be focused on the why and not the what of the code. This is the case for code when something needed to be done and the specifics or reasons behind the implementation wouldn’t be so clear just by reading the code.

Had to use a workaround, a hack, a quick fix? Add a comment explaining why and future actions to take if necessary. Make it clear and short.

After reading this article we hope you’ll be more confident to start documenting your software project. We know it’s difficult but we have the tools for the job and not doing it only harms your team and the future of the software or product.

Try to imagine how complicated it’d be trying to integrate a third party service if they wouldn’t have provided great documentation websites to see examples and understand how they work.

Start with small steps, practice it frequently, and in no time you’ll be adding more docs than ever to the projects you work on.

Like It? Share it!

✉️ Get our latest posts in your inbox!