How to Document an API


I’ve been working on a project where I’ve had to design - and document - a brand new API. The API is RESTful, and exposes services out to a number of clients. Pretty standard stuff.

As part of this project, I needed a way to document how we were designing the API architecture - all the endpoints, data models, all that. In our case, the API hasn’t even been built yet - we’re designing it completely, then going to build it.

API Doc Immaturity

When we kicked off the project, I was focused on creating documents that could be consumed by a development team for building the API. My gut was to make sure the documents were readable and presented nicely. Beyond that, I didn’t really have much of an opinion on how they were put together.

With that in mind, I turned to Slate, an open-source package that provides usable, attractive documentation for APIs. I liked Slate because of the UI - it’s really nicely done, easy to understand, and pretty flexible. Also, creating docs was as easy as writing Markdown (how I write my blog posts anyway), so it felt natural. So, happy with that, I went and started to build the docs.

Getting More Legit

Shortly into building out the docs with Slate, I started to get curious about other documentation standards. Flitting about various Github repos, I stumbled upon API Blueprint, and it was a massive aha moment. API Blueprint is an actual spec! It’s a structured way to define an API, which documents are then automatically generated from.

This felt like a huge improvement. Now, I could manage a spec, but decouple the design/spec of the API from the presentation/docs layer.

I started digging into API Blueprint more, building out nearly the full spec of the API in it. What I loved about API Blueprint was the structured way it approached the design of the API. Create endpoints, define requests and responses for them, indicate parameters, etc. It felt much more organized, and helped me to think through the lower-level bits of the API more intentionally. Also, it was written in Markdown just like Slate, so it felt like a natural transition.

That said, there were things that bothered me about API Blueprint. I hated some of their strict indenting rules (tabs were four spaces, really irked me), and over time, it because difficult to read the spec. At one point, I broke it up into chunks of smaller markdown files (per endpoint) using markdown-pp, and created a shell script that compiled all the individual markdown files into a single markdown file every time I modified one of the smaller files.

Also, there were some odd rules about how endpoints were defined, and I felt like it didn’t give me the kind of flexibility in design I wanted. Too opinionated, too stodgy in its approach.

Workable, yes, but still felt a bit lacking. However, I was onto something at this point: API specs should follow a more structured pattern, and should be decoupled from the docs. Good to know.

Mature API Spec FTW

Still a bit unhappy with how the spec was coming together, mainly due to the formatting issues and increasingly difficult job it was to manage the spec, I started exploring other alternatives to API Blueprint.

That’s when I found Swagger. Now, to people who are familiar with API specs, this isn’t going to be a shock. Swagger is the big kid on the block, arguably the most mature API spec tool out there, and it shows.

(The crappy nature of their website initially turned me off, but I got over it)

Swagger is what API specs should be like. Now on v2.0, it’s a well-reasoned, fully-considered specification for documenting APIs. Plus, the new version of Swagger supports writing the spec in Yaml, a huge bonus IMO.

With Swagger, documentation is easy and effortless to write. Here’s how we might define a spec (taken from the official Swagger demo):


swagger: '2.0'
info:
  title: Uber API
  description: Move your app forward with the Uber API
  version: 1.0.0
host: api.uber.com
schemes:
  - https
basePath: /v1
produces:
  - application/json
paths:
  /products:
    get:
      summary: Product Types
      description: |
        The Products endpoint returns information about the *Uber* products
        offered at a given location. The response includes the display name
        and other details about each product, and lists the products in the
        proper display order.
      parameters:
        - name: latitude
          in: query
          description: Latitude component of location.
          required: true
          type: number
          format: double
        - name: longitude
          in: query
          description: Longitude component of location.
          required: true
          type: number
          format: double
      tags:
        - Products
      responses:
        '200':
          description: An array of products
          schema:
            type: array
            items:
              $ref: '#/definitions/Product'
        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/Error'

To me, this just makes sense. A path - /products - with a set of nested methods underneath (get, post, etc.). Parameters are easy to define, as are responses. You’ll also notice that $ref down there in the responses. That allows you to define a model and reference it on the responses - no more trying to update multiple response signatures when a model changes slightly. DRY FTW.

As if the spec format itself isn’t enough, Swagger brings with it a host of tooling as well. Swagger UI automatically builds documentation from the spec. Swagger Codegen automatically creates client libraries and server-side stubs from the spec (what?!). As if the official tools from Swagger aren’t enough, there are a whole host of projects on Github offering tooling for the spec. Suffice to say, Swagger is the shit, and the way to document APIs IMO.

Swagger is also helping to put ahead the Open APIs initiative, aiming to help create a standardized way of interacting with RESTful APIs between companies. Folks like Google, IBM, Apigee and others are on board, and it’s great to see that kind of initiative shaping up. In today’s ever-increasing service-oriented world, this kind of industry adoption of a single specification for defining the design of APIs is a huge step in the maturity of the field.

I should note that I also looked at RAML, and just about went that direction for documenting the spec. RAML is also a Yaml-based way of doing things, and frankly, is somewhat similar to Swagger in some ways. When it came down to it, however, the wide amount of tooling already available for Swagger kicked it over the edge for me, and I’m really thrilled to be using it.

Why This Is Important

Standardization is important. As we develop more services, it’s going to become more and more critical that we understand how these services operate, and reduce the amount of time it takes for developers to learn the specifics about an API. By standardizing around a specification, we can move toward developing sophisticated tooling around those specs, and help APIs play together more seamlessly in the future. That interoperability is huge, and something all of us should strive for.

So, if you’re looking to document your API (and if you have an API, you need to document it), I’d highly recommend looking at Swagger. It’s incredibly powerful, and just the kind of approach that modern API development really needs.

Have you used Swagger or another documentation tool? Have success or horror stories? Toss them in the comments!

Related Posts

Shitty Sales Have Made Product Development Harder

Shitty, one-sided sales processes have made product development much more difficult for early stage startups.

Why I'm Cold Emailing You

You might have gotten a cold email from me. Tasteless? Some people think so. Here's why I'm doing it.

How I Found Your Email

I've been cold emailing a lot of people, and many folks are surprised that I found their email. Here's where I dug it up.

Announcement: The Most Exciting Thing I've Done

Today, I'm announcing the most exciting project I've been involved with. It's called CrowdSync, and it helps to automate paperwork, communication and logistics when dealing with groups of people. Read on for why this is so big.

How to Post to Private Slack Channels from Zapier

If you automate posting to Slack via Zapier, you might need to post to a private channel. It's not entirely obvious how to do it, but actually pretty damn easy.

Sharing is the Currency of the Web

You consume free content all day on the web. The best way to pay back the people creating it? Share it.

The Magic of Low Fidelity

High-fidelity documentation is great, but it has a hidden dark side. Learn to embrace low-fidelity documentation, and you'll be amazed at the benefits.

Why You Should Blog More (Data)

When you stop blogging, people stop coming. Simple enough. Here's the proof.

Using a Linter Will Make You a Better Dev

Using a linter while you write code won't only make your code better formatted, it'll make you a better programmer.

Everyone Is Self Employed

The idea that you're not self-employed if you work fulltime somewhere is wrong. EVERYONE is self-employed.