Your own API based on Ruby on Rails

Making your own REST(ful) API based on Ruby on Rails is not that hard. There are plenty of libraries that makes it a bit easier, but as you probably know, dependencies are not always a good thing for maintainability.

Why an API?

A great way to open up your application is to enable your users to write their own applications interacting with your web app. While opening up, the users are likely to produce more traffic and more buzz if there is a simple way to integrate your app with theirs.

Planning an API

I've been producing a couple of API's lately and the one and only rule I can think of in general is to start small and add to it. Be responsible when writing the API and try to plan ahead so that you wont have to remove parts of it in the future, which might cause other apps dependent upon your API to fail. Another option is to make versions of the api, so that new changes wont affect apps that consume your API. Consider different endpoints for different versions:

http://myapp.com/api/v1/comments.json http://myapp.com/api/v2/comments.json

How it's done in Rails

Create an "API base controller" that will be inherited from the rest of your API controllers (namespace them or whatever).

# app/controllers/api_controller.rb
class ApiController < ActionController::Base
  attr_accessor :current_user
  prepend_around_filter ApiAuthorizedFilter.new
end

# app/models/api_authorized_filter.rb

class ApiAuthorizedFilter
  def before(controller)
    return true unless controller.params[:api_key]
    controller.current_user =
      User.find_by_api_key(controller.params[:api_key])
  end

  def after(controller)
    controller.current_user = nil
  end
end

This way, we can control authorization with an API key. Additional parameters can of course be taken into consideration when autorizing the user.

Now you can use the 'api_controller.rb' when implementing the api and make each new controller inherit from it like:

# app/controllers/comments_controller.rb
class CommentsController < ApiController
  def index
    Comment.find(:all)
  end
end

You've just accomplished a super easy filter to authenticate/authorize a user via your own Ruby on Rails based API!