Since I love FireBug, and CouchDB has a JSON API, I attempted to combine the two. My goal was to find a way to use jQuery‘s AJAX functions to create, read, and update CouchDB documents.
The first thing I tried was creating a merb project with a single page referencing jQuery, and accessing CouchDB from there. The browser’s security model got in my way, however. A page on one port on localhost can’t access another port with AJAX. I searched for ways to give a page special permission, but my search turned up empty and I figured that I’d rather not go against the browser anyway, if I could help it.
The next thing I tried was getting a page that references jQuery to be served by CouchDB’s web server. That way the page and jQuery’s JSON API would be on the same port and Firefox would be happy. I opened up CouchDB’s Futon Utility Client at http://localhost:5984/_utils/ and found that it already had the latest version of jQuery included! Problem solved.
I opened the FireBug console (which was already enabled on localhost from when I was trying to get it working with my Merb project) and started trying out jQuery’s AJAX functions on CouchDB.
The GET request returned successfully! However, FireBug doesn’t retain the response, so I have to click Load Response to get it.
OK, there’s CouchDB’s welcome message! Expanding the GET request and clicking Load Response is tedious, though, so a better technique is needed. The first thing that comes to mind is doing a synchronous request. I find that get() doesn’t support this option, so I need to use ajax().
Aside from FireBug’s quoting FAIL, it works nicely. What I’d really like, though, is for FireBug to pretty-print the JSON. So I throw an eval() statement around it, and add the left side of an assignment statement because otherwise I would get an error (another way to get it working is to throw square brackets around the expression).
The output is quite a bit nicer, in my opinion.
Creating a Database
To create a database I use the HttpDatabaseApi page on the CouchDB wiki. Creating a database requires use of a PUT request, which can be made with jQuery’s ajax() function if the browser supports it (and Firefox does).
CouchDB returns a simple OK message to let me know it worked.
Creating a Document
Now that I have a database, I can create a document using the HttpDocumentApi. I opt to take the cavalier approach of having the server generate an ID rather than supplying an ID of my own. To do this, I send a POST with the database’s URL for the address and the document’s contents for the POST data. To send the POST data, I call ajax() with the document’s contents (as a JSON expression) for the data option and the string ‘json’ for the dataType option.
It didn’t work. I expand the POST and look at the data sent to find out why.
The ajax() function didn’t serialize the data! It’s not built into jQuery. It makes sense, given that one of jQuery’s features is its small footprint. I remember that when I viewed the source of the main page of CouchDB’s Futon Utility Client I saw a JSON include. It’s in http://localhost:5984/_utils/script/json2.js. It’s not a jQuery plug-in, but its interface is fairly simple. To serialize data, you call JSON.stringify() with an object as the first parameter. I add this to my statement and try again.
It worked! Or, at least, it didn’t error. It returned a globally unique ID (GUID) generated by the server. Now I use the ID to GET the document’s contents.
Only a summary of the object is shown. If I click the object it expands to a full view.
The data is there. The revision number is also present. One of CouchDB’s coolest features is built-in versioning.
After I realized that I was given only a summary of the object, I tried creating a document again and seeing if I missed any info that was supplied in the response to the POST request. It turns out that I did. The revision (_rev) was given. I’d like to have Firebug print out the whole response (and not a short summary), but I don’t see any way of doing so.
Updating a Document
Documents can be updated by sending a PUT request with the document’s URL as the address and the new contents as the data. The new contents must include the revision number upon which the update is based. This is to prevent conflicts. If a revision number other than that of the latest revision is supplied, it means that another client updated it first.
I update the document by getting the latest copy, storing it in a variable, removing the ID (since it’s already in the URL), changing the radius, and sending a PUT request with the new database contents.
The document is updated. If I expand the object I can see the new revision number.
Pretty cool, huh?
Conclusion & Next Steps
Before I tried using CouchDB with Firebug, I tried using the Futon Utility Client. I felt that I learned more and better retained what I learned when I used Firebug. Firebug as it is right now has a couple of issues that will keep me from using it as an environment in which to try doing different things with CouchDB. The first issue is that the pretty-print doesn’t show the full object in the console view, and there’s no option in the UI to make it do so. The second issue is that I find the editor to be insufficient. When the editor is in vertical mode, there’s no way to go through the history of commands entered. When the editor is in horizontal mode, it can’t expand beyond one line. When I switch between tabs, the text in the editor is often lost.
This was fun. I think the next thing I’ll do with CouchDB is try writing a simple wiki using CouchDB and Merb.
Woohoo!! It’s so fun to see people trying out different things with CouchDB! :)
Oh, that Firebug change annoys me so much where it doesn’t load the POST response for you. At work i actually went back to the previous version for exactly that reason.
I believe the AJAX problem you had from the Merb project is to do with the AJAX “Same Origin Policy” to stop you calling pages on another server. I didn’t realise it prevents you going across ports on the same server though!
It is easily overcome by doing an AJAX request to a proxy page on your own site which does something like this:
response = Net::HTTP.get_response(URI.parse(CGI.escape(params[:url])))
render :text => response
I’m really excited to see where you go with Merb and making an application which uses CouchDB directly! :)
I had forgotten that Firebug used to not have the extra step to load responses. I would like it to work the old way for me. I don’t see why it’s not configurable. I hope Firebug hasn’t gone down the path of insisting on a simple UI at the cost of customizability like Gnome has. If it has, perhaps a fork or an extension that interacts with the Firebug extension will be in order.
Such a library could be folded (npi) into futon to make your exercise above a little easier as well as put it into the hands of everyone who has couchdb. Futon could even use it to include a text field within the page giving a command line interface apart from firebug…
@Charlie: It’s called jquery.couch.js
Wow – great article Ben. I just read this now that I too am fooling around with CouchDB. Good stuff! I was just asking this very same question when Chris Chandler was explaining how it worked at hacknight.
I actually like what you have acquired here, certainly like what you are saying and the way in which you say it. The Stability of Case Processing and Sentencing Post http://fbwkqy.com/forum.php?mod=viewthread&tid=253129
Do we have any online demo site for CouchDB just as we have for MongoDB http://try.mongodb.org/