CouchDB's RESTful API

Posted Saturday 1st August, 2009

I’ve recently been playing with Apache CouchDB; a distributed, fault-tolerant and schema-free document-oriented database. CouchDB supplies a RESTful API for the manipulation of data within it. This is a great demonstration of REST at work, so I thought I’d illustrate its usage in a quick post.

Let’s get the technical details out of the way first: CouchDB makes use of HTTP verbs – GET, PUT, POST, and DELETE – and handles requests and responses in JSON only. This means it is entirely possible to utilise CouchDB using JavaScript alone. For the purpose of these examples, however, I’ll be using cURL, which is easier to follow along with via the command line.

My CouchDB server is running on my dev Ubuntu VM, on the default port of 5984. I’ve also set up a “couchhost” alias to the VM in my hosts file, to make my requests more readable.

Creating databases

The first thing we should do is create a database within our CouchDB server. To do that, we use the PUT verb:

$ curl -X PUT http://couchhost:5984/fu
{“ok”:true}

In the command above, we specified the database name in the resource URI – which is the correct usage of PUT – and received a JSON object response. As you can see, that JSON object contains a single field; the boolean “ok”, with a value of true.

We can obtain a list of all the databases on our CouchDB server, by sending it a GET request to the _all_dbs resource:

$ curl -X GET http://couchhost:5984/_all_dbs
[“fu”]

Here we receive an array response containing all our database ids. In this case, we only have our “fu” database.

Let’s try adding another:

$ curl -X PUT http://couchhost:5984/bar
{“ok”:true}

Since we’ve received an ok response, let’s list all the databases again:

$ curl -X GET http://couchhost:5984/_all_dbs
[“fu”,”bar”]

Now we can see multiple values in the array response.

We can obtain information about a specific database by sending a GET request to its URI:

$ curl -X GET http://couchhost:5984/fu
{“db_name”:”fu”,”doc_count”:0,”doc_del_count”:0,”update_seq”:0,”compact_running”:false,”disk_size”:4096}

Here we can see, amongst other things, the number of documents in the database – none – and how much diskspace the database is taking up – 4k.

CouchDB documents

A CouchDB document is simply a JSON object with some associated metadata. This is an example document (lifted from the CouchDB documentation):

{
    "_id":"discussion_tables",
    "_rev":"D1C946B7",
    "Sunrise":true,
    "Sunset":false,
    "FullHours":[1,2,3,4,5,6,7,8,9,10],
    "Activities":[
        {
            "Name":"Football",
            "Duration":2,
            "DurationUnit":"Hours"
        },
        {
            "Name":"Breakfast",
            "Duration":40,
            "DurationUnit":"Minutes",
            "Attendees":[
                "Jan",
                "Damien",
                "Laura",
                "Gwendolyn",
                "Roseanna"
            ]
        }
    ]
}

As you can see, a CouchDB document can handle multiple types of data, including arrays and nested objects. By default the structure is flat; in this particular case, the “Activities” attribute is structure imposed by the user.

It’s also worth noting that any top-level fields with a name that starts with an underscore prefix are reserved.

Adding documents

So let’s define a document for one of our databases:

{
    "FirstName":"Isabella",
    "FamilyName":"Huegdon",
    "Age":2,
    "Likes":[
        "noise",
        "animals",
        "chocolate",
        "kicking Milly",
        "throwing tantrums"
    ]
}

This is a fairly straight forward document that includes several different types of data. To add it to our database, let’s use an HTTP POST request:

$ curl -X POST http://couchhost:5984/fu \
-H 'Content-Type: application/json' \
-d '{"FirstName":"Isabella","FamilyName":"Huegdon","Age":2,"Likes":["noise","animals","chocolate","kicking Milly","throwing tantrums"]}'
{“ok”:true,”id”:”30d53965f5aec18391c258faa66921c1”,”rev”:”2348720638”}

Because we’ve used POST, CouchDB has automagically assigned our document an identifier. You can see this in the id attribute of the response object. But what if we want to specify our own id? Simple; we use HTTP PUT instead.

Let’s define another document:

{
    "FirstName":"Amélie",
    "FamilyName":"Huegdon",
    "Age":2,
    "Likes":[
        "noise",
        "animals",
        "chocolate",
        "hitting Izzy",
        "running and screaming"
    ]
}

And now let’s add that document using HTTP PUT:

$ curl -X PUT http://couchhost:5984/fu/milly-huegdon \
-H 'Content-Type: application/json' \
-d '{"FirstName":"Amélie","FamilyName":"Huegdon","Age":2,"Likes":["noise","animals","chocolate","hitting Izzy","running and screaming"]}'
{“ok”:true,”id”:”milly-huegdon”,”rev”:”3414255320”}

This time, we can see our specified id in the id attribute of the response object.

Now let’s have a look what documents we’ve got in the database, using the _all_docs resource, beneath our database:

$ curl -X GET http://couchhost:5984/fu/_all_docs
{
    “total_rows”:2,
    “offset”:0,
    “rows”:[
        {
            “id”:”30d53965f5aec18391c258faa66921c1”,
            “key”:”30d53965f5aec18391c258faa66921c1”,
            “value”:{“rev”:”2348720638”}
        },
        {
            “id”:”milly-huegdon”,
            “key”:”milly-huegdon”,
            “value”:{“rev”:”3414255320”}
        }
    ]
}

Note: I’ve styled the response here for ease of reading; your cURL output will lack indenting but will contain the same information.

Here we can see, from the total_rows attribute, that there are 2 documents in our database; and we can see the metadata for those documents in the rows attribute array.

To obtain the actual document, we just need to send an HTTP GET request to the document’s URI:

$ curl -X GET http://couchhost:5984/fu/milly-huegdon
{
    “_id”:”milly-huegdon”,
    “_rev”:”3414255320”,
    “FirstName”:”Am\u00e9lie”,
    “FamilyName”:”Huegdon”,
    “Age”:2,
    “Likes”:[
        “noise”,
        “animals”,
        “chocolate”,
        “hitting Izzy”,
        “running and screaming”
    ]
}

Once again, I’ve styled the response somewhat for readability. In this instance, you can also see that CouchDB can handle unicode characters (since JSON should always be encoded as UTF-8) from the FirstName attribute.

Deleting items

Deletion of documents and databases from our CouchDB server couldn’t be simpler. All we need to do is send an HTTP DELETE request.

To remove the bar database we created earlier, we send the following request:

$ curl -X DELETE http://couchhost:5984/bar
{“ok”:true}

Summary

You are now able to create and delete items from your CouchDB database. This is all you’re going to need if you just want to use CouchDB as a persistent document store; however, if you want to query the data in your databases, you’re going to need to make use of CouchDB Views. I’ll cover those in a later blog post.

I’m going to continue to play with CouchDB over the next week or so and will continue to blog about it (with the hope of using the blog posts as the basis for a TechTalk at Yahoo! Europe – slides possibly to follow on SlideShare). For now, you should be able to see that CouchDB is a wonderfully easy thing to use, thanks to its entirely RESTful API and its use of JSON as a request and response format.

Included in: API, Apache, CouchDB, Development, HTTP, Linux, REST, UNIX

Categories:

  1. Accessibility
  2. Agile
  3. Ajax
  4. Apache
  5. API
  6. Architecture
  7. Books
  8. Browsers
  9. CMS
  10. CouchDB
  11. CSS
  12. Design
  13. Development
  14. Django
  15. Email
  16. Events
  17. Gaming
  18. Grammar
  19. Hardware
  20. HTML
  21. HTTP
  22. Humour
  23. Idea
  24. Information Architecture
  25. JavaScript
  26. jQuery
  27. Lean
  28. Life
  29. Linux
  30. Literature
  31. Mac OS X
  32. Management
  33. Meme
  34. Microformats
  35. Monday
  36. MySQL
  37. Networking
  38. News
  39. Personal
  40. Photoshop
  41. PHP
  42. Process
  43. Python
  44. Reference
  45. REST
  46. Science
  47. SEO
  48. Server
  49. Site
  50. Sitepimp
  51. Social
  52. Spelling
  53. Syndication
  54. Testing
  55. The Future
  56. Thoughts
  57. Tools
  58. Tutorial
  59. Tutorials
  60. Typography
  61. UI
  62. UNIX
  63. Virtualisation
  64. Web
  65. Web Standards
  66. Widgets
  67. Wii
  68. Writing
  69. Xbox
  70. XHTML