More advanced Blueprint with MSON.

By on

In the previous post "Writing API specs with Apiary and Blueprint" I explained how to create a first API with the basic Blueprint elements.

In this post, I will show you how you can get rid of JSON examples in your specification. When your API grows, you will come ultimately to a point when you start to copy/paste that JSON.

Using MSON

And as we all know:

CTRL-X, CTRL-C, CTRL-V is the axis of evil.

  • Grumpy Grobmeier, on some training session (Maybe somebody else said it too, but I think I was first)

Let us look at what we have now:

+ Response 200 (application/json)

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

Of course, JSON gives us some type hints already but defining what is required and what not or even naming this object is hard.

This is where MSON comes in. MSON is a "Markdown Syntax for Object Notation". As the name suggests, it's compatible with JSON and aims to describe it even more.

In your API specification over in Apiary, you should create a new section on the bottom (or where ever you want, I just find it suitable there) called "Data Structures".

Then you can add an entity definition already. It could look like this.

# Data Structures

## Person (object)

- id: 123 (number)
- name: Christian (string, required)
- surname: Grobmeier (string, required)

As the second headline, you see the name of the entity followed by its type "(object)" which refers to the JSON type object.

As a list below this name there the definition of the objects properties, including the type definitions which we already know from the other blog post!

Let us it now:

## Person Collection [/persons]

### Get all persons [GET]

+ Response 200 (application/json)
    + Attributes
        - data (array[Person])

I added a new action to the collection "/persons" which should return all persons we have. Hopefully, it's not too many!

In the response type, I added a new list called Attributes. It will render as an object with a member field called "data", containing an array of Persons.

In Apiary, the result looks like the following.


That's already pretty, and of course, you can use MSON in the Requests as well. With that, you have reusable objects and your docs update, whenever you change something on the data structure.

Multiple response types

Sometimes it is necessary to demonstrate the use of a specific parameter.

Looking at an example in the previous post, we used an action like:

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

In real life, one could call it like: /persons/123?include=metadata and the returned result would -surprise- include metadata. How to show that in the docs?

It's also easy: as long as you name your Request sections, you are free to go with multiple of them. The full listing would look like this:

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

+ Parameters
    + id: 123 (string, required)
    + include: metadata (string, optional)
        + Members
            + metadata
        + Default: metadata            

+ Response 200 (application/json)

    + Attributes (Person)

+ Request with metadata (application/json)

+ Response 200 (application/json)

    + Attributes (PersonWithMetadata)

The Parameters part is already known to you. The first Request is implicit if there is nothing to do. Then I added a second request which is named "with metadata".

The response can be different now; you can use different MSON objects.

"Extending" from other MSON definitions

In the case above you, unfortunately, need a different a fully different model, and that's painful. A lot of member fields stay the same, updating would be a huge pain.

Luckily we can include fields from the original model!

It looks like that:

# Data Structures

## Person (object)

- id: 123 (number)
- name: Christian (string, required)
- surname: Grobmeier (string, required)

## PersonWithMetaData (object)

- Include Person
- meta (object)
    - created: 2015
    - editor: 1234

Now we have two different objects, and it's halfway sane to maintain them.

Wrapping it up

MSON is a pretty nice way to deal with objects, yet it is not perfect. There are some parts of it which will make you scratch your head. But again, it will work for 95% of the cases - at least for me.

Extending is crucial when your project grows, and you should not miss the opportunity to make extensive use of data structures.

You can find the Apiary docs online.

And the source code is on GitHub.


Tags: apiary, blueprint, rest, specification, documentation