I've recently installed CouchDB but, still being pretty new to this whole document store thing, don't really know what they can do or how to make CouchDB do it.

The best way to learn, of course, is to do. I've decided that I'll implement a simple address-book implementation.

Investigation and technology choice

Since CouchDB talks JSON I figure that I'll write the address book in Javascript and HTML, and because CouchDB includes a web server I'll serve the application from the same place I store the data. I'll call the file that contains that addressbook application addressbook.html.

Taking a peek at the CouchDB configuration in /usr/local/etc/couchdb/couch.ini I see that the document root for the web server can be found at /usr/local/share/couchdb/www - that's where the addressbook.html file will go.

I'll need a database to store people's contact details in. There's a pretty nice interface to do this at /_utils/ which is accessible using a web browser by pointing it at the CouchDB server's IP address and port.

CouchDB comes with a Javascript wrapper which can be found at /_utils/script/couch.js but it only talks to a local server and I'm accessing the page across the internet so I'll steal some code from it and change it to work for my setup.

Implementation

First off, create the database. Jump into the interface at /_utils/ and create a database called "addressbook". That's where we'll store our data.

The user interface is going to be a webpage using Javascript which makes things pretty simple. I'll whip up a really simple page to start with.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <!-- The javascript will live in addressbook.js -->
  <script src="http://aaa.bbb.ccc.ddd:5984/_utils/addressbook.js"></script>
  <title>Address Book</title>
</head>
<body>
  <h1>Address Book</h1>
  <div id="addressbook">
    <p id="loading">Loading... please wait...</p>
  </div>
</body>
</html>

Since I've been spoiled by ActiveRecord I want to be able to say something like var people = Person.find("all"); in my code and have it return all Person records. I also want to be able to say Person.find("123456-1234-1234-123456"); to find an individual person.


Person = {
  // Push the implementation details of the database into a 
  // different object to keep Person clean.
  //
  database: AddressBook,
  find: function(id) {
    if(id == "all") {
      return this.database.allCards();
    } else {
      return this.database.openCard(id);
    }
  }
}

I've chosen to implement an AddressBook object that will abstract the details of database connection from the Person object. It will provide two methods, allCards and openCard(id). These methods talk to the CouchDB server and handle any and all data marshalling or other tricky bits and pieces.

AddressBook = {
  // Change this to point to your own CouchDB instance.
  uri: "http://craig-01.vm.xeriom.net:5984/addressbook/",

  _request: function(method, uri) {
    var req = new XMLHttpRequest();
    req.open(method, uri, false);
    req.send();
    return req;
  },

  // Fetch all address book cards.
  allCards: function() {
    var req = this._request("GET", this.uri + "_all_docs");
    var result = JSON.parse(req.responseText);
    if (req.status != 200)
      throw result;
    var allDocs = [];
    for(var offset in result.rows) {
      var id = result.rows[offset]["id"];
      var doc = this.openCard(id);
      allDocs[allDocs.length] = doc;
    }
    return allDocs;
  },

  // Fetch an individual address book card.
  openCard: function(id) {    
    var req = this._request("GET", this.uri + id);
    if (req.status == 404)
      return null;
    var result = JSON.parse(req.responseText);
    if (req.status != 200)
      throw result;
    return result;
  }
}

I push responsibility for parsing JSON off to another library. Luckily, Yahoo provide a rather nice JSON library that does just what I'm looking for - I don't have to implement it, but I do need to pull it into the webpage, and make it appear in the global namespace.


<!-- Add this to the head of addressbook.html -->
<script src="http://yui.yahooapis.com/2.5.2/build/yahoo/yahoo-min.js"></script>
<script src="http://yui.yahooapis.com/2.5.2/build/json/json-min.js"></script>

// Make YUI JSON available in the global namespace.
// Add this to addressbook.js
JSON = YAHOO.lang.JSON;

The last piece of Javascript I need to show the address book is something to load all people from the address book and add them to the page. This uses window.onload hook which is bad, but for this little application is a quick and easy to kick off some code.

// This is horrible, I know, but it's just a simple example.
window.onload = function() {
  var addressbook = document.getElementById("addressbook");
  var personList = document.createElement("ul");
  for(var offset in people) {
    var person = people[offset];
    var personNode = document.createElement("li");
    var name = document.createTextNode(person.name);
    personNode.appendChild(name);
    personList.appendChild(personNode);
  }
  addressbook.removeChild(document.getElementById("loading"));
  addressbook.appendChild(personList);
}

That's it; the application is ready to go. Upload the addressbook.html and addressbook.js file to the document root of the CouchDB server, fire up your browser and navigate to http://aaa.bbb.ccc.ddd:5984/_utils/addressbook.html where aaa.bbb.ccc.ddd is the IP address of your CouchDB instance.

A blank page that says "Address Book" should greet you. Not very impressive, right? What went wrong? Actually, nothing went wrong. There's just no data in the database.

The interface that I pointed out before for browsing and creating databases can also be used to add documents to the database. Jump into it again, navigate to the addressbook database and add a document. When it asks you for an id, just leave the field blank: it'll create one automatically. Add a field to the document called name and click the little green checkbox beside the textbox, then double click on the value of the new field and set it to your own name in quotes eg "Craig Webster". Click the green arrow beside the textbox then click "save document", jump back to the address book and hit refresh. The new record should now show up.

Moving forward

I've shown how to retrieve data from CouchDB using Javascript, but currently the data still has to be input using the CouchDB interface. Watch this space for an upcoming article on manipulating the database using Javascript so we can add cards to the addressbook.

Did this article help?

If this article helped you, I appreciate beer if you meet me, or recommendations at Working With Rails.

written by
Craig
published
2008-06-28
Disagree? Found a typo? Got a question?
If you'd like to have a conversation about this post, email craig@barkingiguana.com. I don't bite.
You can verify that I've written this post by following the verification instructions:
curl -LO http://barkingiguana.com/2008/06/28/getting-started-with-couchdb-a-simple-address-book-application.html.orig
curl -LO http://barkingiguana.com/2008/06/28/getting-started-with-couchdb-a-simple-address-book-application.html.orig.asc
gpg --verify getting-started-with-couchdb-a-simple-address-book-application.html.orig{.asc,}