Installing, Configuring, and Deploying I/O Docs

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 Ploymath. 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.REDISTOGOURL) {
  // use production (Heroku) redis configuration
  // overwrite config to keep it simple
  var rtg = require(‘url’).parse(process.env.REDISTOGOURL);
  config.redis.port = rtg.port;
  config.redis.host = rtg.hostname;
  config.redis.password = rtg.auth.split(“:”)[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);

Closing

I plan to start contributing to the I/O Docs project once I become more familiar with git/GitHub (I know). I’d like to add some additional configuration options, like passing parameters (such as the API key) in the request headers.

In the meantime, you’re welcome to download my app.js. All other changes should be configuration specific to your environment.

Unexpected behavior with drop-down option order using minYear, maxYear in CakePHP

I noticed something interesting when testing a checkout form today build in CakePHP. The options for the drop-down were in descending order. The options were for the credit card expiration date field. The range was set with minYear and maxYear attributes.

The code in my view (CakePHP version 1.3.7).

echo $this->Form->input('cc_expires', array('type' => 'date',
  'label' => 'Expiration Date',
  'dateFormat' => 'MY',
  'empty' => true,
  'separator' => ' ',
  'minYear' => date('Y'),
  'maxYear' => date('Y', strtotime('+7 years')));

Although the options range is correct, this seemed unintuitive. In addition, I felt it was slightly poor usability. So I wanted to fix the order.

CakePHP default option order

CakePHP default option order

I dug around in The Book. Nothing. I was about to submit a ticket. But before I do, I typically check my version and the core. Upon searching for minYear I found the function in question – year(). Apparently an undocumented attribute exists – orderYear. After adding 'orderYear' => 'asc' to the options array I got the desired output.

Two notes here. First, CakePHP has many undocumented features. It never hurts to dig around the core. Second, the orderYear attribute is completely unnecessary in this case. In fact, it is only used for the *year* drop-down. It could be easily determined from comparing minYear and maxYear. In this case, minYear is 2012 which is less than maxYear is 2019. Display in ascending order.

Control option order using orderYear for year in CakePHP

CakePHP option order with orderYear

Maybe orderYear has uses. But today it wasted my time.

</rant>

Installing node.js, npm, and redis on Mac OS X

I’ve been wanting to mess with I/O Docs for some time now. I/O Docs requires node.js, npm, and redis. I hear the buzz around these technologies, but I have yet to use them. Although I found several posts and a package for installing node.js and npm on Mac OS X, each had issues. Mac OS X runs atop BSD Unix. So, while potentially intimidating, you can install all these yourself by running commands within Terminal.

Installing node.js

After much Googling I discovered an overwhelming set of node.js installation instructions. In a nutshell (no pun), this installs node.js under a newly created local folder in the current user folder and adds that folder to your PATH so you can run node.js simply by typing node.

echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bash_profile
source ~/.bash_profile
mkdir ~/local
mkdir ~/node-js
cd ~/node-js
curl http://nodejs.org/dist/node-v0.4.7.tar.gz | tar xz --strip-components=1
./configure --prefix=~/local
make install

A few notes.

First, this installs node.js version 0.4.7. From what I read, this is currently the most compatible version. If you require a different version, I’ll assume you know more about installing node.js than me.

Second, bash on Max OS X uses .bash_profile not .bashrc. I’ve modified the original script to reflect these changes.

Installing npm

Once you have installed node.js, you can install npm with just one command.

curl http://npmjs.org/install.sh | sh

I should pass along the warning that this runs commands streamed from the internet. If you’re paranoid about that kind of stuff, you should download and verify install.sh first.

Installing redis

Redis was a straightforward install. For the most part I followed the redis quickstart guide. I modified the script below slightly to use curl as Mac OS X does not include wget.

curl -O http://redis.googlecode.com/files/redis-2.4.4.tar.gz
tar -xzf redis-2.4.4.tar.gz
cd redis-2.4.4
make
rm redis-2.4.4.tar.gz

In closing

In time, you may need to update the versions for node.js and redis. Both offer a latest download. Feel free to substitute these into your script. The commands above should still work. Nonetheless, I tried to provide links to the original documentation when available.

Check out my recent post if you are interested in getting started with I/O Docs.

Tough Mudder Challenge

In two weeks I, as part of team #tigerblood, will accept the Tough Mudder Challenge. This course, located in northern Indiana, will consist of 21 obstacles over 12 miles. The course is over rough terrain with elevation changes, water, and mud. I expect to be wet the whole time. Since winter is coming the cold will be a factor.

Each Tough Mudder course is different. But the following video demonstrates the most common obstacles. You also see the fine line between toughness and craziness.

Why?

A man should measure himself against a strong force at least once in his life to see if he can handle it.

Tough Mudder is as much about physical endurance as it is mental will. In addition, several of the obstacles are designed to require a group effort. Many races or events are about the individual. I like the camaraderie Tough Mudder adds. You have to band together to complete it. Finally, Tough Mudder isn’t about results. There are no times, no scores, no places. It’s about finishing.

Preparation for Tough Mudder

I trained for 5k races in the summer. So I had a base to start Tough Mudder training. I added weight lifting and the Tough Mudder workout to the weekly routine.

Any opportunity to add grit to the training was taken. My parents had an uprooted tree that needed removal. Instead of a chainsaw and trailer, we used axes and carried the logs. Before our long weekend runs we dump buckets of water on ourselves. I’ve started running home from work once a week. Particularly on the days that it rains.

Goals

I have no idea how difficult Tough Mudder will be. My goal is to finish – run the course and complete all the obstacles. I hope to have fun and stick together as a team.

Review of PHPMyAdmin 3.4

A few month ago I needed to install PHPMyAdmin on my new Macbook Pro. At that time, PHPMyAdmin 3.4.3 just released. After installing PHPMyAdmin 3.4.3, I immediately noticed the theme and user interface changed. At first, I welcomed the change. The new theme, pmahomme, was clean and modern. So dramatic that someone asked what I used during a demo in my talk at WordCamp Chicago.

Unfortunately the euphoria was short lived. The user interface changes soon outweighed the new theme. With due respect to the “reluctance to change” and “learning curves”, I question some of the decisions made in PHPMyAdmin 3.4. Here’s my quick list the UI pros and cons of PHPMyAdmin 3.4.3. Let me disclaim that I use PHPMyAdmin as a development tool.

PHPMYAdmin 3.4 Pros

  • Faster response times. In addition to undoubted PHP optimizations, the combinations of jQuery and CSS make the UI much faster.
  • Inline query editing. While the pop-up window works, this UI is much more streamlined. Probably the single best feature.
  • Create table button in table list. Before you had to go to the database home page (or Operations), scroll down, and add a table. PHPMyAdmin 3.4 could go further, having this button at the top and bottom (for large table lists).

PHPMYAdmin 3.4 Cons

  • Removal of Empty and Drop tabs from table navigation. While I appreciate these are not technically navigation options, burying them under Operations was not the right move. If nothing else, taking features away is always a dangerous game. I have to say PHPMyAdmin lost me on this one. As a developer, these actions, particularly Empty are incredibly common.
  • Hiding of Export options. Instead of displaying all options, like previous versions, the UI is now that of a decision tree. In addition, the options themselves changed. Again, this is an often used feature for me. I could export unconsciously in previous versions. It seems, even after months, I’m continually scanning the options in PHPMyAdmin 3.4.

All in all, it appears that PHPMyAdmin 3.4 caters to new users. I suppose you can’t fault them for appealing to the masses. Yet for my usage the cons of PHPMyAdmin 3.4 outweigh the pros. Although I’ll probably stick with it on my personal server, I have left PHPMyAdmin 3.3 on our work servers. Those extra clicks spread across 4 developers add up. As far as the new features, well, ignorance is bliss.