Writing API specs with Apiary and Blueprint.


The first APIs I wrote sucked, but its specification and docs sucked even more. I was lacking oversight and could not see issues with my work.

Recently I was asked to write another API, and my goal was to suck a little less than before.

One of my friends recommended me Swagger.io and another said I should go with Apiary.io which uses the open Blueprint specification.

I found Swagger confusing. It uses YAML, which I don’t like that much. Blueprint uses Markdown which I work a lot with anyway. Despite Apiary is a proprietary tool I finally decided to try it. There are open source tools available which generate your docs from your source. If Apiary starts to suck (I need to use that word less often), you can move out.

In the end, Apiary turned out to be a fantastic tool which you should use when learning Blueprint.

Blueprint itself is very nice and usable but has some corners and edges as well. Luckily, the format is still in development.

Specifying API specs

How to define a first rest resource

Everything begins with some header:

HOST: http://api.grobmeier.de/

# My API

The first line is for the tools to recognize you write Blueprint. The second line is used from Apiary to give you an ability to test directly from the editor against the live API.

And the first markdown headline is your APIs name.

Now the real fun begins!

Let us start with defining a collection, which is a set of resources.

## Person Collection [/persons]

As you see, it has square brackets at the end, which names the resource. The collection is on ## level, which is more or less Heading 2.

You can already use this resource to create a new person.

### Create a new person [POST]

As we are using the same resource as defined above, we don’t need to define a specific resource. Just naming the action “POST” is enough, so the resource “/persons” is assumed.

Here is our request/response:

+ Request (application/json)

            "name": "Christian",
            "surname": "Grobmeier"

+ Response 200 (application/json)

            "id": 1235,
            "name": "Christian",
            "surname": "Grobmeier"

Request and Response are both keywords and part of a Markdown-List. I also added a content type at the end, and in the case of the Response even a HTTP status code.

As the actual payload, I just put some JSON into it, as pre-formatted source code. It’s a bit tricky, but you need to intend it proper, so it’s recognized. The Apiary editor is a huge help in identifying that kind of issues.

Of course, using JSON all over your API spec is maybe nice and readable for smaller specs, but when your work grows, it might become a bit inflexible. There is a solution for that, which is called MSON.

Here is how it looks in Apiary.


Now that was easy! What about requesting the just created person 123?

URL Templates

When you want to get the data for a person with the ID 123, you usually would send a GET to /person/123.

Let’s do it! In the “persons” collection I add the following:

### Get a person [GET /persons/{id}]

As you see, we are shadowing the collections URL template and add {id}. This parameter should be used to select our person.

We don’t need Request body so we can leave it out.

But we need to define what {id} is, and that is done using the Parameters block. The full listing would look like this:

### Get a person [GET /persons/{id}]

+ Parameters
    + id: 123

+ Response 200 (application/json)

            "id": 123,
            "name": "Christian",
            "surname": "Grobmeier"

As you can see above, the Parameters are just defined like we did with the Request. That way you can even define multiple URL params.

In example:

### Get a person [GET /persons/{id}/{name}]

+ Parameters
    + id: 123
    + name: Christian

But how would you define optional parameters, like it could be the case with query strings?


### Get a person [GET /persons/{id}{?include}]

+ Parameters
    + id: 123
    + include: metadata

With the above we make clear include is a query param because it’s defined by the question mark. Multiple query parameters are comma separated:

### Get a person [GET /persons/{id}{?include,version,format}]

At this point, you might want to add some more information on your parameters. You can dot this by adding some more type information:

+ Parameters
    + id: 123 (string, required)
    + include: metadata (string, optional)
    + format: xml (string, optional)

Apiary shows it pretty decent:


But let us not stop here. We might only support three different formats, like XML, JSON, and HTML (ugh), and the default would be JSON. Let’s nail that down too.

+ Parameters
    + format: xml (string, optional)
        + Members
            + xml
            + json
            + html
        + Default: xml

For brevity, I left out the other params. “Format” does have an example now and we do not only know it’s a string and optional.

We also know the allowed values from the Members list and, of course, the default setting by the Default keyword.

Apiary also supports it just fine!


Wrap it up

We have seen it is very easy to define resources using Blueprint and the Apiary support for visualizing them is great so far. You’ll reach some corners when Apiary is not that nice, but in 95% of all cases, you should just be fine.

The Blueprint spec supports URL templating, can group resources into collections and also allows to specify what your params are and if they are required.

You can see the specification on Apiary.

The source for this API is on GitHub.

In the next post, we will speak about MSON, which helps you remove pure JSON and reuse object definitions.


Tags: #apiary #blueprint #rest #specification #documentation