Camping with CouchDB

When developing a new system, getting end-to-end functionality and being able to demonstrate it as soon as possible is important. While doing so, it’s also an added benefit if you do not spend a lot of time writing throwaway code.

I have a set of scripts that let me test and use the system that I am developing from the command line. Since the whole system is written in Ruby, writing a script to allow command line interaction is straightforward. The end result of what I am developing will be a service, so functionality equivalent to the scripts must be available in a browser. With Ruby, there are several ways to bring an application to a browser. The usual suspects are Rails, Merb and if they don’t work, one can always revert to using WEBrick and write servlets.

Rails and Merb did not seem right since I have an existing CouchDB backed model. I had read about Campingand wanted to test it out so I did. This was great. From the time I started investigating Camping until I could show data from my model in the browser took only 45 minutes. When I realized that I could use my own model directly rather than use the Camping model, I was just a few lines from the goal. I haven’t given much thought to whether this is a production ready framework, but that doesn’t really matter at the moment since I don’t have to write much unnecessary code. The benefit of reduced development time while retaining the full programmatic control of my model.

To show how easy it is to connect CouchDB and camping, here’s a simple example that while not particularly useful on it’s own should show a pattern that you can use in your own application.

require 'camping'
require 'couchrest'

Camping.goes :MyCamp

I use CouchRest to simplify CouchDB interaction. The magic is of course in the last line, Camping.goes :MyCamp. That line tells Camping to serve the module called MyCamp.
Time to implement the controller. Note that Camping expects to find the controller definitions in MyCamp::Controllers.

module MyCamp::Controllers
  class MyObject < R '/object/(\w+)'

This construct might confuse people, but R is defined by Camping and the parameter is a path with a regexp in the parentheses. This regexp yields the argument to get below. In this case, any HTTP GET request to server/object/number1 will call get('number1'). Perfectly RESTful.

    def MyObject.set_storage(storage)
      @@storage = storage
    end

This is a way of letting the controller know the about our CouchRest model. I could have added a Model encapsulating that, but to me that is just adding another level of indirection that only serves to add confusion and complicate code maintenance since the model already exists.

    def get(id)
      @my_object = @@storage.get(id)
      @my_id = id
      render :mymodel
    end
  end
end

This is the method that is called by a HTTP GET request matching the pattern given /object/(\w+). render :mymodel result in the execution of the mymodel view.

module MyCamp::Views
  def mymodel
    body do
      h1 "#{@my_id}"
      ul do
        @my_object['items'].each do |field, value|
          li "#{field}: #{value}"
        end
      end
    end
  end
end

Simple view that iterates over the ‘items’ hash and lists field: value. Note that Camping by default uses markaby to create HTML programmatically.

db_url = 'http://localhost:5984/'
storage = CouchRest.database("#{@db_url}objects")
MyCamp::Controllers::MyObject.set_storage(storage)

Sets up CouchRest to use the CouchDB backend at http://localhost:5984/objects

Run you application with

camping my_camp.rb

If the database contains a document with _id = 'number1' and 'items' = {"a": 1, "b": 2}, your browser will show this at http://localhost:3301/object/number1:

number1

  • a: 1
  • b: 2

There you go, a nice little Camping application backed by CouchDB.

For the official Camping site, go to http://camping.rubyforge.org/

One thought on “Camping with CouchDB

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.