read

Other videos in this practice series:


Two years ago I finished the first edition of Build APIs You Won't Hate, and since then I've worked on bigger and better projects, using my API experience, honing some approaches, and throwing out some approaches entirely.

These projects were big and scary. I did some things I'm not proud of, and in general - between the anarchy - I just wanted to get away from a computer and ride my bike. Now I'm back, ready to share my experience, and have a video series in the works.

To get this video series ready, I've been doing a series of LiveCoding.tv semi-frequently. These iPhone headset recorded noisefests have generally been me covering certain topics, while I forget how things work and google around to remind myself, but they've been instrumental in getting the series off the ground.

While that series is still being worked on (with my fancy new audio getup), I've decided to share some of these rough sessions, to help people out in the meantime.

The first video is a topic I've covered a bit in the past: Documentation with API Blueprint. So, check out the video, and the notes that go with it:

Source Code

Interested in a Proper Series?

These rough videos will be replaced with a nicely recorded series, and to get updates about that, just let me know your email address.

Notes

There are a few specification languages available, my favourite API Blueprint, and other popular alternatives Swagger (Open API) and RAML.

API Blueprint is built by the folks behind Apiary, which is a hosted product for hosting your documentation and providing tooling around it. Whilst I do not use Apiary itself for every project, it's a great place to start when it comes to building out documentation as the tooling is very easy to learn, and their plans start at free.

FORMAT: 1A
HOST: https://api.example.com/

# Example API

GET /message
+ Response 200 (text/plain)

        Hello World!

With a basic Hello World of documentation showing up, we now need to build out some realistic documentation.

Just doing that off the top of your head is tough, so lets make a simple bullet list of resources and attributes that we'd like to see.

For this step, imagine you're working with the whole team, writing up this list of fields in a Dropbox Paper, Google Doc, tmux session, codepad, etc.

- products
  - name
  - description
  - style
  - apv
  - image_url
  - relationships
    - manufacturer
    - recent_reviews

- manufacturers
  - name
  - about
  - city
  - country

- reviews
  - body
  - rating
  - name
  - relationship
    - user
    - product

- users
  - username
  - full_name
  - email
  - password

Skip having relationships on the user. If you pile too many relationships on the user as they can get really slow. Use links sure, but having all the IDs for each user means it has to make multiple SQL queries for it all. Things get slow.

Data Structures

Reusable structures that can be put into requests and responses, with basic validation supplied.

We can easily convert the bullet points we just wrote into data structures using API Blueprint syntax:

# Data Structures

## Products
  - name
  - description
  - style
  - apv
  - image_url
  - relationships
    - manufacturer
    - recent_reviews

## Manufacturers
  - name
  - about
  - city
  - country

## Reviews
  - body
  - rating
  - name
  - relationship
    - user
    - product

## Users
  - username
  - full_name
  - email
  - password

Now they'll vanish from the output because they're secret hidden data.

Onto grouping. stuff.

# Group Section

## Resource Section

### Action Section

To put this syntax into action, we can build out our products section.

# Group Product

## Product Collection [/products]

### Retrieve All [GET]

- Response 200 (application/json)

    - Attributes (array[Product])

Next we'll need to add POST. We could manually specify a Body, but instead, let's once again use MSON:

### Create a Product [POST]

- Request (application/json)

    - Attributes (Product Create)

- Response 201 (application/json)

    - Attributes (Product Full)

Then update the data structures:

# Data Structures

## Product Create (object)
- name: Old Bristolian (string, required) - Name of the product.
- description: Tastes like apple juice but knocks you on your arse. (string,
  required) - Text description of outlininig taste and stuff.
- type: cider (enum[string], required) - Is it made from apples or pears.
    - cider
    - perry
- apv: 7.4 (number, optional)
- image_url: `http://example.com/ciders/old-bris.jpg` (string, optional) - URL
  of cider photo.

## Product Full (object)
- id: djkfh34t234t (string, required) - Unique identifier.
- Include Product Create
- relationships (object)
    - manufacturer
    - recent_reviews

To add a filtering endpoint, we can add another GET. API Blueprint will initially be upset about having two of the same HTTP method on the same URI, but for the filter we'd like to change the URI anyway. We can override the URI simply by providing it after the method.

### Filter Products [GET /products{?type}]

- Parameters

    - type (enum[string], optional) - Should the response return cider, perry or
      all.
        - Default: all
        - Members
            - all
            - cider
            - perry

- Response 200 (application/json)

    - Attributes (array[Product Full])

Next up, deleting stuff:

### Delete a Product [DELETE]

- Response 204

Nothing particularly interesting to say there. It does what it says on the tin.

For updates, we can start by documenting the happy path.


### Update a Product [PATCH]

- Request (application/json)

    - Attributes (Product Update)

- Response 200 (application/json)

    - Attributes (Product Full)
        - type: perry

Here we send a new data structure, much like Product Create:

## Product Update (object)
- type: perry

When we send this update, we can expect a response to come back, which will be the normal Product Full, but with the type value overridden to be perry now.

If we wanted to show off successful and unsuccessful values, we could do that with having Multiple Transactions. Transactions in API Blueprint are the same as transactions in the world of HTTP in general: the pairing of a request and a response. You can have as many transactions as you like under your Action, by providing an arbitrary string as a name after the Request keyword.

### Update a Product [PATCH]

- Request Successful Update (application/json)

    - Attributes (Product Update Valid)

- Response 200 (application/json)

    - Attributes (Product Full)
        - type: perry

- Request Unsuccessful Update (application/json)

    - Attributes (Product Update Invalid)

- Response 422 (application/json)

    - Attributes (Error Unprocessable Entity)
        - message: `This was an invalid type, please select from cider or
          perry.`
        - attribute: type

Here we have a few new data structures: Product Update Valid, Product Update Invalid, and Error Unprocessable Entity. They're simple enough:

# Data Structures

...

## Product Update Valid (object)
- type: perry

## Product Update Invalid (object)
- type: wine

## Error Unprocessable Entity (object)
- title: Unprocessable Entity
- message: This resource could not be updated due to invalid arguments being
  passed.

Fin.


If you're into APIs, I've written a whole book called Build APIs You Won't Hate, and it's available in ebook or paperback form! If programming books normally bore the crap out of you, this book is for you.

Blog Logo

Phil Sturgeon

I used to contribute to the PHP-FIG, The League of Extraordinary Packages, PHP The Right Way, CodeIgniter, FuelPHP, PyroCMS and a bunch of other stuff, but I gave it all up to join the circus.

Book Cover

Build APIs You Won't Hate

Everyone and their dog wants an API, so you should probably learn how to build them.

Buy it from LeanPub or Amazon.

Image

Phil Sturgeon

I used to contribute to the PHP-FIG, The League of Extraordinary Packages, PHP The Right Way, CodeIgniter, FuelPHP, PyroCMS and a bunch of other stuff, but I gave it all up to join the circus.

Back to Overview