Develop With Style

The Right Way to Create an API

I know, I know, it’s been tooooo long. But whatever!

At Shermans we have begun a large project to rebuild the architecture around the travel deals system. And guess what? we chose to do it all in Ruby! Yay!

The deals server (as we are calling the entire system) will consist of a few separate apps, mostly Rails. A few of these apps will be REST based web API’s, allowing our partners and publishers to fetch deals. Surprisingly, there are very few Ruby Gems available to help with creating an API. But that probably has more to do with the great support for exposing resources built in to Rails using respond_with and co.

But based on my experience building the Codaset API, I knew I wanted a better way to expose the “views” for the API. For example, I don’t want all attributes of my model to be exposed, and Rails doesn’t provide a simple way to do that. Enter RABL!

RABL bills itself as an API templating language, but all it really is, is a way to expose and define your API attributes from within the view itself, which is exactly the way it should be done, as it is only the view that has any concern with this. Exposing or defining the attributes for the API is not the responsibility of the model or even the controller.

Let’s say our controller assigns the @posts instance variable, which is thusly available in our view, and our view looks like this:

lang:ruby
1
2
3
4
collection @posts
attributes :id, :title, :price
child(:user) { attributes :full_name }
node(:read) { |post| post.read_by?(@user) }

Which would look like this as JSON:

lang:javascript
1
2
3
4
5
6
7
[{ post :
{
id : 5, title: "...", subject: "...",
user : { full_name : "..." },
read : true
}
}]

This means you don’t have to dirty your controller with code that should be in your view.

From Zero to Hero: How I Built Twitious in Two Weeks

… and that wasn’t even part time!

I’ve been using Twitter for quite a while now, and I have quickly found that every time I come across a site or web page of interest - I will tweet it. And quite often, I have found myself either forgetting to add these links to my bookmarks in Firefox, or just not bothering. But that’s not good, as also quite often, I remember I tweeted a link that I need to refer back to, but just can’t remember the damn thing.

Twitter has become my primary means of bookmarking. But there is a problem with that - Twitter doesn’t give me an easy way to see all those bookmarks. It is for that reason that I promptly set about building a web app that will make it easy for me to find all my tweeted links and organise them by hashtags.

I came up with the idea of Twitious just two weeks ago, and it went live just three days ago, and now now has over 15,000 bookmarks! An achievement that I am extremely proud of. Don’t get me wrong, it’s not a complex app, but everything you see was created from scratch by myself - part time. I have a very busy full time freelance job remember. Not to mention Codaset.

The app was built with Rails 3 on Ruby 1.9.2. I originally had intended to use MongoDB as the data backend, but settled with the tried and tested MySQL setup. Simply because I didn’t actually see a reason not to. It’s running on an Ubuntu slice at Slicehost, under Nginx and Passenger 3. In fact, pretty much every part of the stack is the latest and greatest, which was really fun to do. (no legacy shit to deal with)

Obviously, the app communicates with the Twitter API quite a lot, as every time a user signs up for Twitious, the app needs to scan through the users entire timeline, and parse out any links and hash tags. And it also needs to do that on a regular basis to ensure Twitious shows the latest links from each users tweets. I needed to run all this as background tasks via some sort of queueing system. This was a bit of a no-brainer too. I went with my trusted old friend; Resque, which I already use with Codaset.

There is plenty more that I want to do with Twitious, but I think it’s already a really efficient way to create and manage your bookmarks; especially if you are already using Twitter. So please feel free to check out Twitious and sign up. It’s completely free, so why the hell not! And I would love to know what you think.

Dynamic Form and Dynamic Errors for Rails 3

Rails 3 is awesome! BUT

For some unknown reason, the powers that be decided to remove the error_message_on and error_messages_for form helpers. I’m not sure about every one else, but I use these in pretty much every single form that I create, so I just have no idea why it was removed.

Fortunately, all is not lost. The code for these helpers was extracted out into a plugin called dynamic_form. But unfortunately it doesn’t seem to have been kept up to date, as the last commit was back on June 12th. Running the tests failed all over the place, simply because the HTML returned has changed slightly in the release candidate. So I took it upon myself to fork the code and managed to get the tests passing with Rails 3 RC. I then also packaged it up into a Gem which you can grab now and install in your Rails 3 app.

My next task was to get the custom-err-msg plugin working with Rails 3. But rather than fix and refactor that as it is, I decided to simply integrate it into the dynamic_form plugin, as it’s functionality is closely related.

So the dynamic_form plugin has been enhanced a little, so please install and let me know what you think. I’ve put in a pull request to the official dynamic_form repo, so hopefully they will accept that soon. But in the meantime, you can still use my version by simply running gem install dynamic_form or adding to your Gemfile (if you are using Bundler) gem "dynamic_form".

Handling Dates in MongoDB

I’ve been using MongoDB quite a bit recently in several different projects, and it kicks ass. But the hardest thing to learn and to get used to with Mongo, is it’s schemaless structure. With SQL databases like MySQL, you always have a defined and very rigid structure, which is of course the schema for each table you create. You create a table with a few columns; each column has a set type, a length, and a whole host of other variables.

It’s this rigid structure that most of us have gotten used to for years, and that is the hardest thing to shake off when using NoSQL databases such as MongoDB.

But that is not to say that Mongo has no defined structure. In fact, that is far from the truth. Mongo and all schemaless databases have defined structure, but the difference is that that structure is defined by you. And that is what makes Mongo so cool. No need to actually create any tables and define each column - Just insert some data in your own defined way.

But there is a side effect of this schemaless idea. Even though you no longer have to define a schema in the traditional sense, you still have to think about the structure of each collection, and how that will look. In fact, there is a lot more to think about, as there are a lot more ways to structure your data with Mongo and other schemaless databases.

It’s somewhat of a steep learning curve, but well worth sticking with. I’m still leaning the best ways to structure certain data types, and dates is one that I think I’ve nailed.

Converting HTML Entities to Characters With Javascript

So I use Ajax quite a bit in many of my projects. And why not? It kicks ass! I have one project which dynamically updates specific elements of an HTML page via Ajax. Something like this:

javascript
1
2
3
$.get('/travel_guide/Paris', function(data){
$('#advice').text(data);
});

The problem I have, is that sometimes that data can include HTML entities like & and >, and for reasons I don’t want to bore you with, I cannot do anything about it on the server side. When inserting a block of text that contain HTML entities into the DOM, those entities are not parsed as such, and get printed exactly as they are.

jQuery UI Autocomplete and Caching Query Results

I’ve never managed to find a really good jQuery based autocomplete plugins, especially one that is flexible and easily extensible. So when the jQuery UI team released 1.8 back in March, I was intrigued to find that they included - amongst other new widgets - an autocomplete widget. And it turns out to be pretty damn good, and flexible to boot.

So when I had a need to add the ability for a local data source for the autocomplete plugin that we use on ShermansTravel QuickSearch, I gave the new jQuery UI widget a go.