Documentation - Build APIs You Won't Hate: Everyone and their dog wants an API, so you should probably learn how to build them (2014)

Build APIs You Won't Hate: Everyone and their dog wants an API, so you should probably learn how to build them (2014)

11. Documentation

11.1 Introduction

Regardless of whether you decide to keep an API private or release it to the general public, documentation is incredibly important.

In the very early stages of development some API developers will rely soley on a Postman collection (discussed in Chapter 8: Debugging) to be a sufficient source of documentation for their API. This may be the case but as soon as the API is in use by more people than just the one developer with their one collection this quickly becomes a nightmare.

Even if the API is in use internally, without a single source of regularly updated documentation for your API you will be answering questions from anyone using the API about how that works non-stop.

If the API is public then… well without documentation nobody will use your API at all, which could drastically effect the successes of your company. Integration with services via an API these days is a very important factor for many companies, from startups to huge corporations, so do not go through the trouble of building something amazing only to have it completely ignored due to a lack of documentation.

11.2 Types of Documentation

There should be a few different types of documentation:

API Reference

The “API Reference” is sometimes refered to as “Endpoint Reference” and is essentially a list of all endpoints and their associated HTTP Methods, descriptions of what they do and a list of all arguments that can be passed with descriptions about what values work and in what format those values could be. That is a lot of work. But, it can be made easier with some tools. More on that later.

Sample Code

“Sample Code” is generally just a case of building one or two libraries or code packages in different languages and documenting their API with tools like phpDocumentor and showing lots of common scenarios, like “Search venues by name” and “Create a checkin with a photograph” to show the basics of how that code works. These examples reduce the mental barrier for a developer because they can see concrete examples in a language familiar to them, instead of being forced to think in terms of HTTP requests.

Despite your own personal preferences, please for the love of every good in the world make your sample code look as good as you can in each language. Words cannot express how frustrating it is when some Ruby developer smashes out some awful PHP code - because they are bad with PHP - and passes that off as a finished product.

Regardless of the language, most sample code should look very similar. This has the benefit of letting users switch between languages without having to start from scratch learning a new code package. PHP, Ruby and Python all have some concept of namespaces, they all have blocks or callbacks, they all have objects and hashes, they all support variadics and one day PHP will support named parameters. One day.

Guides or Tutorials

This is the easiest of the lot. Take a subject like “Authentication” and talk through it like a blog post. Images, diagrams, code examples of the libraries handling various situations in one or multiple languages using tabs, etc. Some people show examples using command line curl, but that can get pretty nasty as curl is not exactly known for being an interface full of sugar.

A great example of a set of tutorials is the SoundCloud API. Their “Using the API” page is a central resource which links to the API Reference for those who want to get their hands dirty, but also contains simple scenarios like “Uploading Audio Files” in multiple languages.

SoundCloud API Documentation - "Using the API"

SoundCloud API Documentation - “Using the API”

If you check the examples out here Ruby, Python and PHP all look near identical (although I am not sure what happened to JavaScript).

Writing these guides takes a bit of time but that time will be given back in buckets, saving you answering the same questions over and over again. The other time saver is for when future you forgets how things work in 3 months, or you come back from a holiday rather frazzled and need a tutorial to step you through how things work. The amount of times I Google search a problem and find a blog I have written a few months ago answering it… It happens.

There are plenty of great tools around for static text-based documentation like this. Generally any Markdown -> HTML static site generator works well; Sculpin (PHP), Jekyll (Ruby) and Hyde (Python) all do this as well as each other.

11.3 Picking a Tool

There are no doubt multiple tools out there for generating your API/Endpoint documentation. Some recommend a system called Swagger which is a great looking tool and works with a huge array of languages. Sadly to me it seems to be somewhat of a black art.

Swagger defines a specification and various language or framework specific implementations come up with their own solution. For PHP the way you go about this is through a rather confusing (and poorly documented) set of annotations with strange names. Furthermore it requires you to put these annotations throughout a large chunk of your application, including data mapper style models, which you might not even have. It wanted property-level annotations, and neither my models or Fractal transformers have properties, so this was a wild and whacky way to try and work.

Another tool called API Blueprint takes care of this nicely. A company called Apiary released this tool as open-source, and as their entire company is about API generation it seems like rather a good fit.

11.4 Setting up API Blueprint and Aglio

API Blueprint has a very easy to understand set of Getting Started instructions which has a series of approaches to creating your documentation with various languages and tool combinations. They are working on a Ruby utility and .NET seems to be covered. Sublime Text has [a plugin][st-plugin], but by far the easiest is the command-line executable called Aglio.

There is one caveat: this tool uses NodeJS. That sounds like a blocker to some but it should not be. Only the command-line utility requires NodeJS, much like some command-line tools require Ruby or Python. Install NodeJS and move along to the next bit.

Step 1: Install NodeJS

If you are using OSX then Homebrew makes this very easy:

1 $ brew install node

Otherwise the NodeJS website has instructions for your operating system.

Step 2: Install Aglio

Install this utility as a command-line executable:

1 $ npm install -g aglio

The -g switch installs the utility globally, instead of just into the current folder.

Step 3: Generate Example Docs with Aglio

The sample code for the book includes the Aglio example markdown file, which will help illustrate how easy it is to generate documentation HTML:

1 $ cd ~/apisyouwonthate/chapter11/aglio-example

2 $ aglio -i example.md -o index.html

Step 4: Generate HTML and Open in Browser

Create some sort of web server (XAMPP, WAMP, MAMP, Pow, shove it on FTP or whatever) and view the contents. This book has used PHP as an example before, so let us continue that trend:

1 $ php -S localhost:8001

Now browse to that address in your favorite browser and you should see some very attractive sample output.

Example output of Aglio generated HTML

Example output of Aglio generated HTML

Looks amazing right?

Step 5: Find a Plugin

Writing Markdown then switching over to the terminal and running a command can be a tricky workflow, so try and find a plugin for an editor you like which can help. If you use Atom then there is an Atom plugin you can use, but there are doubtless other options available.

11.5 Learning API Blueprint Syntax

To make the output reflect your API documentation, the Markdown source files will need updated. While they are generally just Markdown, there is a specific format to this, known as “API Blueprint format 1A”.

Go to the following location and open up example.md:

1 $ cd ~/apisyouwonthate/chapter11/place-example

The rest of this section will walk through this example.md and explain what various parts mean.

Meta Data

This is simple. The API title, URL, introduction, etc is just some Markdown:

Very start of an API Blueprint markdown file, showing meta data


1 FORMAT: 1A

2 HOST: https://api.example.com

3

4 # FakeSquare API

5

6 This is documentation for the theoretical checkin app API that has been built throughout t\

7 he

8 book [Build APIs You Wont Hate](https://leanpub.com/build-apis-you-wont-hate).

9

10 ## Authorization

11

12 This could be anything, but it seems like a good place to explain how access tokens work.

13

14 Most endpoints in the FakeSquare API will require the `Authorization` HTTP header.

15

16 ```http

17 Authorization: bearer vr5HmMkzlxKE70W1y4MibiJUusZwZC25NOVBEx3BD1

18 ```

19

20 Failing to do so will cause the following error:

21

22 ```json

23 {

24 "error" : {

25 "code" : "GEN-MAYBGTFO",

26 "http_code" : 401,

27 "message" : "Unauthorized"

28 }

29 }

30 ```

31

32 Or something. This is mostly just an introduction, so provide links to tutorial

33 sections elsewhere on your site.


A very quick and easy introduction, showing the name of the API (FakeSquare API) and a basic example of how to authenticate a request with our API.

Resource Groups

To keep this simple but also cover a lot of different usages, we will take examples from the “Action Plan” in Chapter 2: Planning and Creating Endpoints for Places, and document them in API Blueprint syntax.

Places - Create - Read - Update - Delete - List (lat, lon, distance or box) - Image

Using the same logic in Chapter 2 as we used to outline the user endpoints, we can assume these endpoints:

Action

Endpoint

Create

POST /places

Read

GET /places/X

Update

PUT /places/X

Delete

DELETE /places/X

List

GET /places

Image

PUT /places/X/image

Everything at or below the /places level is considered a “Resource Group” by API Blueprint, so our new example will only have one group.


1 # Group Places

2 Search and manage places.


That first line has the reserved keyword Group which will be removed from output. The Places is the name of the group. The line below is an optional description for humans.

In a real API you would have more groups. Users, Checkins, Posts, etc.

Resources

API Blueprint accepts multiple Resource sections per Group section, and considers /places, /places/X and /places/X/image to be different Resources. You probably consider /places to be more of a collection of resources, and consider /places/X/image to be a “sub-resource”, but API Blueprint considers them all “Resources”.

Not a problem. Simply make some h2 tags using the ## prefix:

Example outline of multiple ‘Resource Sections’.


1 ## Place List [/places{?lat}{&lon}{&distance}{&box}{&number}{&page}]

2

3

4 ## Create new place [/places]

5

6

7 ## Places [/places/{id}]

8 Manage an existing place.

9

10

11 ## Place Images [/places/{id}/image]

12 Places can have an image associated with them, that will act as a cover photo or photograp\

13 h.


Here we have four “Resource Sections”, each for a different resource. The one oddity here is that there are two entires are for /places. The reasoning here is that each “Resource Group” has its own “URI Template”. No two groups can have the same template (two with /places would error) and if you want to document parameters then you need to put them in the template.

It seems odd, but just go with it.

1. One Resource Section for listing (with the filter/query/search parameters listed)

2. One Resource Section for creating a new item on a collection

3. One Resource Section for a single item

4. One Resource Section for each and every “sub-resource” your API may have on an item

Resource Actions

Actions are what you would expect them to be - the actions outlined in the “Action Plan”.

You can spot an “Action” in two ways. Firstly due to the h3 header (###) and secondly by the trailing [GET] HTTP verb notation.

Example of the ‘Place List’ resource using API Blueprint Markdown


1 ## Place List [/places{?lat}{&lon}{&distance}{&box}{&number}{&page}]

2

3 ### Get places [GET]

4 Locate places close to a certain set of coordinates, or provide a box of coordinates to se\

5 arch within.

6

7 + Parameters

8

9 + lat (optional, number, `40.7641`) ... Latitude to search near, with any accuracy

10 + lon (optional, number, `-73.9866`) ... Longitude to search near, with any accuracy

11 + distance = `10` (optional, number, `20`) ... The radius size in miles to search for \

12 from lat and lon coordinates

13 + box (optional, string, `40.7641,-73.9866,40.7243,-73.9841`) ... Top left latitude, t\

14 op left longitude, bottom right latitude, bottom right longitude

15 + number (optional, integer, `15`) ... The number of results to return per page

16 + page = `1` (optional, integer, `15`) ... Which page of the result data to return

17

18 + Response 200 (application/json)

19

20 {

21 "data": [

22 {

23 "id": 2,

24 "name": "Videology",

25 "lat": 40.713857,

26 "lon": -73.961936,

27 "created_at": "2013-04-02"

28 },

29 {

30 "id": 1,

31 "name": "Barcade",

32 "lat": 40.712017,

33 "lon": -73.950995,

34 "created_at": "2012-09-23"

35 }

36 ]

37 }


This is the first “Resource Section”, now filled out. It lists the available parameters for the URL with a very special syntax:

1 + <parameter name> [= `<default value>`] [([required | optional ], [<type>], [`<example va\

2 lue>`])] [... <description>]

3

4 [<additional description>]

5

6 [+ Values

7 + `<enumeration element 1>`

8 + `<enumeration element 2>`

9 ...

10 + `<enumeration element N>`]

Our example has used slighty shorter syntax and skipped the additional description and enum values, but takes advantage of much of the first line.

1 + lat (optional, number, `40.7641`) ... Latitude to search near, with any accuracy

This explains that the field is optional, it is a number (these type fields are arbitrary) and shows an example value of 40.7641.

The ... is literal here and is used as a marker. Everything on the right hand side is a short description for the field.

1 + page = `1` (optional, integer, `15`) ... Which page of the result data to return

Similar, but this time a default value has been added which in the case of pagination will probably be 1.

The rest of this “Action Section” is responses.

Show an example response for a specific content-type.


1 + Response 200 (application/json)

2

3 { ... }


This says that you can expect a 200 status, which will be Content-Type: application/json and shows an example of the body content.

Now if we run Aglio again and serve it up through a web-server:

1 $ aglio -i example.md -o index.html

2 $ php -S localhost:8001

Example output of Aglio generated HTML

Example output of Aglio generated HTML

How amazing is that, for such a little amount of Markdown? Doing all of that manually certainly would not be any fun.

Requests

Documenting the request content and offering examples is of course one of the most importants parts of any API documentation, and API Blueprint does not disappoint.

API Blueprint will allow you to create multiple Request examples for an Action. Looking at the Place Images Resource will outline how this is done:

Example of the ‘Place Images’ resource.


1 ## Place Images [/places/{id}/image]

2 Places can have an image associated with them, that will act as a cover photo or photograp\

3 h.

4

5 + Parameters

6

7 + id (required, integer) ... The unique identifier of a place

8

9 ### Set place image [PUT]

10 Assign a new image or replace the existing image for a place.

11

12 + Request (image/gif)

13

14 + Headers

15 Authorization: Bearer {access token}

16 + Body

17 <raw source of gif file>

18

19 + Request (image/jpeg)

20

21 + Headers

22 Authorization: Bearer {access token}

23 + Body

24 <raw source of jpeg file>

25

26 + Request (image/png)

27

28 + Headers

29

30 Authorization: Bearer {access token}

31 + Body

32

33 <raw source of png file>


Here the <raw source of png file> stuff is just plain-text - because pasting in the contents of an actual PNG file would not look great - but you can use JSON or anything else.

Having multiple request examples can be very important if you are unfortunate enough to be documenting an API which supports more than one input format, like JSON and XML for instance.

Responses

Each endpoint in your API will have one or more different responses. There will probably be one or more 20xs, some 40xs, and maybe a few 50xs too.

An “action response section” might look like this:


1 + Response 201

2 + Response 400 (application/json)

3

4 {

5 "error" : {

6 "code": "GEN-FUBARGS",

7 "http_code" : 400,

8 "message": "Content-Type must be image/png, image/jpg or image/gif"

9 }

10 }

11

12 + Response 404 (application/json)

13

14 {

15 "error" : {

16 "code" : "GEN-LIKETHEWIND",

17 "http_code" : 404,

18 "message" : "Resource Not Found"

19 }

20 }


A tricky thing here is that while your API might return a 400 code for multiple reasons, API Blueprint will not be happy about having multiple responses listed with the same HTTP code.

This is only thrown as a warning and may only be related to Aglio and not API Blueprint itself - as the documentation seems to display fine. Either put multiple body examples next to each other, or add multiple response items with the same code and ignore the warnings.

11.6 Further Reading

The example.md file provided contains more examples than highlighted in this chapter.

There is more to learn on the API Blueprint repository, including more examples. Their wiki has extensive documentation of the “API Blueprint 1A Format” syntax too.

Between this chapter and those articles you should be documenting your own APIs within no time.