The past few weeks have been nothing but great. The work Kieran and I have been doing has finally start to take some good form and we are coming close to have a beta version release.

We had some bumps across the road but something that really stood out for me was the architectural design of the API.
Most of the times I find myself on the other side of the API, consuming instead of creating.
In this project though, we are having to create the API from scratch.

That’s a very good opportunity to put in practice experience of using other APIs through out the years. More than once I have caught myself complaining that an API is missing this  or that it should have implemented that, etc.
Now I can actually decide what should be included on the API and how the API should behave, which makes me think about all the bad experiences I had with other APIs and make sure I don’t make the same mistakes others did.

With that being said, Kieran and I found ourselves in more than one occasion having to go back and revise some decisions we had made towards the API. Sometimes related to the wording, functionality, response structure, etc.
Spotting errors and fixing them is good, however we also needed to document what the changes were so we could all be on the same page when it came to the latest state of the API. To make sure we could always tell what was the latest features supported by the API without having to go and browser through the source code we decided to create a reference page containing all the API calls and their respective responses.

At first we created the reference page in the README file of the github project, which worked for a bit, but it proved hard to navigate and display the data in a user friendly way, plus we knew that in the future we would need to come up with a better alternative, and that takes me to my next point.

Searching for the right tool

After looking at how other projects were doing in respect to their documentation we started to lay down a plan.

I remembered reading a blog post  a while back listing how the documentation for Popcorn.js was created. The post was from David Seifried, you can check it out here.

Basically the documentation for Popcorn is powered by Jekyll:

Jekyll is a simple, blog aware, static site generator. It takes a template directory (representing the raw form of a website), runs it through Textile or Markdown and Liquid converters, and spits out a complete, static website suitable for serving with Apache or your favorite web server. This is also the engine behind GitHub Pages, which you can use to host your project’s page or blog right here from GitHub.

Jekyll seems like a really good choice since it is already supported by github pages and allow a way to decouple the documentation from the actual project, creating some flexibility when it comes to hosting.

After playing a bit with Jekyll I realized that it could be used for our project, however, I needed to find out a way to display the docs in an organized way and with a nice template, that set me on a different journey looking into several project documentation websites.

The one that really caught my attention was the expressjs.com
The API is listed on a simple and clean way, really easy to navigate.
I decided then to use the same style for the Virt Manage docs.

Having spoken with TJ (the maintainer of express) a couple of times I shoot him an email asking if it was cool to use his template as a baseline, he couldn’t have been nicer and said it was all good.

I then cloned the repo for the expressjs.com on github and started hacking around.

I must say that at first it was a little bit confusing to follow the logic being used to generate the docs, but after changing some things here and there I got a good grip on it.
The structure for the docs is very simple and elegant, focusing on scalability and l8n.

I’ll try to give a short overview of how the docs are structured, which might change in the near future:

Docs root

virt-node-docs-root-ls

The structure is very straight forward.
All the html, javascript and css files are placed in the root.
The directories are:

  • images – All the images used by the docs
  • includes – Code snippets reused across multiple files
  • virt-en – Documentation of all API pieces in English

It is important to note that after defining the skeleton of the docs the only files that need to be changed are the ones in the virt-en directory, which for now are only being listed in English, however, if in the future we decide to add other languages we can easily create another dir, such as virt-fr which can contain all the API documentation in french, without affecting the overall structure of the docs.

Another thing you might also notice is that some files have the .html as well the .jade extension.
The reason for it is that the files are coded using jade, and the Makefile generates the html files which are served to the end user.

Makefile:

[sourcecode language=”bash”]

JADE = ./node_modules/.bin/jade

HTML = index.html
virt-api.html

docs: $(HTML)

%.html: %.jade
$(JADE) –path $< < $< > $@

clean:
rm -f *.html

.PHONY: docs clean
[/sourcecode]

Include dir

virt-node-docs-root-includes

The include directory has some files reused across the docs, such as header, menu and footer for example

API dir

virt-node-docs-api

The API dir is divided into three sections:

  • Server
  • Client
  • Crawler

Each directory contains the documentation for all the API calls for each part of the application

API Server|Client|Crawler dir

virt-node-docs-api-server-ls

The server dir for example has a file for each API call

The file server-listvms-group.jade:

[sourcecode language=”javascript”]
section
h2(id=’server.listvms-group’)
|GET /list/vms

p
|Returns a list with the information of all instances being managed by all libvirt hosts

h3 Format
ul
li
|JSON

h3 Authentication Required
ul
li
|YES

h3 Response Elements
ul
li err
ul
li Can have three different values
ol
li The error message of the command execution
li The stderr output of virsh
li Null if the command is sucessful
li instances (Array of objects)
ul
li id
ul
li Unique Identifier of the virtual machine instance
li name
ul
li The name of the virtual machine instance, which is also a uniquely identifier
li status
ul
li The current status of the instance, possible options:
ul
li Status 1
li Status 2
li Status …
li ip
ul
li Ip of the libvirt host that is managing the virtual machine instance

+js.
{
err: "Error message example"
instances: [
{
id: "Instance ID",
name: "Instance Name",
status: "Instance Status",
ip: "10.0.0.0"
},

{
id: "Instance ID",
name: "Instance Name",
status: "Instance Status",
ip: "10.0.0.0"
},

]
}
[/sourcecode]

In the end that’s what the current API reference page looks like:
Screen Shot 2013-02-18 at 11.29.36 PM

To see the documentation in action you can check out the code on github

Big thanks again to TJ Holowaychuk
You can find his work here and the expressjs documentation here