Documenting REST-Services

I've decided to focus my private programming efforts back on the single project that received a little attention in the world: bootprint-swagger.

Creating this project was actually an accident. I was working on other, really important things, but that's another story.

What is a Rest-Service?

When I last tried to explain somebody what my project is for, I realized that it is so specialized that you have to explain the basic terminology even to people that have a knack for technology:

bootprint-swagger is a tool to create readable static documents (i.e. books) from a Swagger-definition. But what is a Swagger-definition? A Swagger-definition documents a REST-services in a machine-readable way. But what is a REST-service?

Let me try...

Websites

You know the internet, right? We know the internet mostly as websites (at least my generation). In the early days, its purpose was just: I have a website and you watch it. And watching it means: You have a browser (Internet Explorer, Firefox, Safari, Chrome) and your browser talks to my server. You enter a URL, your browser tells my server to send it the correct file and displays the file on the screen.

Nowadays, the browser has become more like a talking device. We talk to servers on the internet. We tell them to show us a file, ok. But we also tell them do transfer money to other people's bank accounts, to send us things and to send messages to all of our friends. We use the browser to translate our wishes into something that the computers can understand and vice versa.

Services

When you watch a website, your browser gets a lot of presentation information mixed with the actual data. What color should the menu be? What's the width of the menu on the left side? It also contains more text than the actual data, like page headers and navigation menus, and even JavaScript code for interactivity or animations. Those things are necessary to create a nice (or sometimes annoying) presentation for you.

Now, imagine, it's not you and your browser talking to the webserver, but another program. Imagine, you want to be notified when the stock price reaches a given limit and you want to write a program that checks the prices periodically. Your program doesn't need all that presentation information. I just needs the stock prices. If the service provider wants to support this kind access to her data, she will provide not only the website for you to watch the prices. She will also create another web-page that is not really a page, but just the actual stock data.

If you go to http://myprovider.com/stock-prices you get a website with all the colors and markup that tell the browser to draw tables and display a pretty site.
If you go to http://myprovider.com/api/stock-prices you get this:

{ "Allianz": "20.0", "IBM": "30.0", "Apple": "40.0" }

That data is not nice to read, but your program knows what to do with it (i.e. beep twice, when IBM is below "15.0").
There more: You can use a similar service to post data, so you can write a program that automatically orders stock, when the price is below the limit and sell it, when the price is higher. You don't have to do anything anymore, just wait for the money to come in (that's just for illustration, it's not as easy as that).

In order to let you do that, your service provider needs to give you access to several URLs (i.e. "web-pages") that represent a programming interface. Your program can use this interface to talk to the internet server; request stock-prices, place orders, sell stock and so on. As a programmer, you will need to know, which URLs exist, which operations can be performed and which data has to be transmitted in what data-format.

You will have to read some documentation, and the service-provider will have to create it. Something like the github api.

Swagger

In my last project at work, we created such a service, and we needed to create documentation so that the other project partners could write programs that talk to ours. In the past, I had documented the different URLs, descriptions and parameters using Microsoft Word. This is possible, but it is far from convenient. It's a lot of work to make the documentation look good and consistent. You have to do all the layouting yourself and I have come to think that Word is not very good at writing code examples (such as the stock-prices above): Sometimes it's autocorrect-features will uppercase the first letter of a word, even though the word must clearly be used in lowercase in the URL. I wanted to have a standard way to do so, and tools that other people were already using.

After a little research, I came across Swagger: Swagger relates to your webservice documentation in the same way a REST-service relates to a website: It is an exact specification of how to write you service documentation. A strongly simplified example of the stock-price interface would look like this:

{
    "info": {
        "description": "This is an api to trade stocks.",
        "version": "1.0.0",
        "title": "Stock Trader"
    },
    "host": "myprovider.com",
    "basePath": "/api",
    "paths": {
        "/stock": {
            "get": {
                "description": "Retrieve the current list of stock prices"
            }
        },
        "/stock/{company}/buy": {
            "post": {
                "description": "Place an order to buy stock of a company",
                "parameters": [
                    {
                        "name": "company",
                        "in": "path",
                        "description": "The company of which you want to buy stock. Every key of the result of the /stock-resource is possible",
                        "type": "string"
                    }
                ]
            }
        }
    }
}

This basically describes a URL http://myprovider.com/api/stock that returns a list of stock-prices and a URL http://myprovider.com/api/stock/Allianz/buy that allow you to by "Allianz" stock. There is a lot more to it, you can read th whole spec or have a look at the petstore-example.

Ah, the petstore-example... What made my excited about Swagger was that once you write your docs in Swagger, you get a documented testing interface for free. You can see which requests exist, and you have an interface to try each of them. Isn't that cool.

There are a lot of other things. You can create client code, so that you don't have to care about URLs in your program anymore. Just call the generated functions. And, if you have a program that provides a GUI to define the general structur service (like ours), chances are good that you are able to create a Swagger-specification automatically (or at least the basic stucture).

The niche to fill with my project

I wanted to create static documentation for our project that we could send to our customer by e-mail. I found the swagger-codegen project which can generate a static website from a swagger-spec, but is not easily adaptable to custom styles, and the generation process requires tools (Maven) that not everybody has installed on his computer.

There wasn't a budget for this, but on a free day, I thought: "How hard can it be. Just combine a few libraries: nodejs, less-css, Bootstrap and Handlebars, some templates and ... done. How hard could it be.".

Well, it might have taken two hours to make the first draft. But it certainly many days (of two hours) to implement every aspect of the Swagger-specification (some parts are still missing). Here is what it generates from the above stock-prices definition.

Webservice

To enable more people to use the project, I've decided to create a webservice. For now, it's just the bootprint-swagger playground and you are not supposed to use it with internal, secret or private.
But in the future it might be available for private purposes as well, against a small monthly fee.

You don't have to install any dependencies, just go to the site, paste your spec and click "Make readable". You don't have to care about maintenance and you are always using the newest version of bootprint-swagger.

Have a look at it, if you are interested. And let me know, if you are interested in premium services of any kind. I'm also interested in how you generate your documentation at the moment, so I could think of ways to integrate bootprint in that process.