Installing, Configuring, and Deploying I/O Docs

Main Thread January 13, 2012 • 4 min read

Update: My fork of I/O Docs is now available on GitHub.

I heard about I/O Docs in a tweet from @Mashery last August. One of their evangelist developed I/O Docs with node.js and released the project on Github. I've wanted to check it out for two reasons. First, I have an undocumented private API – PocketBracket – that, well, I said it already, was undocumented. Second, I wanted a reason to develop with node.js.

From the I/O Docs synopsis:

I/O Docs is a live interactive documentation system for RESTful APIs

Some of the highlights of I/O Docs:

  • live and interactive
  • Promotes RESTful APIs
  • Documentation is done in JSON

Installing I/O Docs

The README within the project provides pretty good instruction for getting started with I/O Docs. It notes the changes you need to make to each file as well as full detail on how to begin documenting your API using their JSON format.

Unfortunately they gloss over the prerequisites for node.js and redis. If you're running Mac OS X, check out my previous post on installing node.js, npm, and redis on Mac OS X. Otherwise, the links they provide should get you started.

Configuring I/O Docs

Out of the box some of the sample APIs did not run. After setting "debug": true; in config.json, I noticed these were the API requests only passing an API key. After revisiting GitHub, this was a known issue which lead me to a fork by ezarko.

I applied ezarko's patches to app.js and config.json. This got me most of the way there. I also had to add the following to unsecuredCall() (~ line 504):

options.headers["Content-Length"] = Buffer.byteLength(options.body);

Unfortunately the DELETE requests still failed for my PocketBracket API. I realized I was expecting the API key as part of the request body. I/O Docs still appended it to the query params. For a minute I questioned my API architecture. However, using the request body for a DELETE did not violate the constraints of REST or the HTTP spec. In fact, to me, it seems more intuitive. In my opinion, only a GET request should explicitly utilize the query params.

I made a few changes to ensure DELETE requests utilized request body properly. I provide my app.js file below. So in summary, I audited the code for DELETE requests and ensured they behaved like PUT/POST (2 places). I also had to modify the if statement to ensure the request body was sent with the request (~ line 600).

Deploying I/O Docs to Heroku

While running I/O Docs locally worked, I needed to share the documentation with my team. Heroku to the rescue. Heroku is a cloud hosting service that plays nicely with git, node.js and redis. In this case, all were free add-ons. The sign up process for Heroku was simple and I was ready to deploy an app in minutes.

I started following a post about deploying I/O Docs to Heroku by Princess Polymath. Unfortunately as noted in my comment on her post, it didn't get me all the way. Although it ran fine locally, I received an error regarding the redis configuration when running on Heroku.

Heroku required some configuration changes in more spots than Princess Polymath noted. I added the following updates to app.js while to be minimally invasive (I hate hacking core code).

Modify the config object before creating the redis connection (~ line 60).

if (process.env.REDISTOGO<em>URL) {
  // use production (Heroku) redis configuration
  // overwrite <code>config to keep it simple
  var rtg = require(‘url').parse(process.env.REDISTOGO</em>URL);
  config.redis.port = rtg.port; = rtg.hostname;
  config.redis.password = rtg.auth.split(&ldquo;:&rdquo;)[1];

Modify the port (end of file)

//  use production (Heroku) port if set

var port = process.env.PORT || config.port;

app.listen(port, config.address);


I plan to start contributing to the I/O Docs project once I become more familiar with git/GitHub (I know). My fork of I/O Docs is now available on GitHub. All other changes should be configuration specific to your environment.

Find this interesting? Let's continue the conversation on Twitter.