Sunday, April 25, 2010

Fab.js: Filter

‹prev | My Chain | next›

Ooh! Shiny new apps are available in fab.js, so I must give at least one a whirl. I opt for fab.filter because it seems like a prime candidate to interact with the CouchDB changes API (and this after I swore off CouchDB / fab.js interop last night).

Again, I start with my skeleton fab.js script:
with ( require( "../" ) )

( fab )

( listen, 0xFAB )

// code here

( 404 );
Between listening and 404 land, I define a "change" handler that will proxy requests back and forth between my CouchDB seed database:
  ( /^\/changes/ )

( fab.nodejs.http, "http://localhost:5984/seed/_changes?feed=continuous" )
Nothing new there, I am just making use of fab.nodejs.http to request the changes API to send changed documents continuously. But what happens if I am only interested in changes to "bar" documents? Sure I could load a filter design document into the CouchDB database, but who wants that hassle? I'd like to filter them in my fab.js server.

My first attempt:
  ( /^\/changes/ )

( fab.filter ( function (obj) {
return /bar/.test(obj.body); } ) )


( fab.nodejs.http, "http://localhost:5984/seed/_changes?feed=continuous" )
Running the fab server and then accessing the changes resource, I find... nothing.

Ugh.

At this point, I take some time to introduce my favorite debugging tool into my fab.js arsenal: print-stderr. Print-stderr is a timeless tool, that can be used in fab.js by defining "puts" at the top of the file thusly:
var puts = require( "sys" ).puts;
...and then using it liberally:
( fab.filter ( function (obj) {
for (var prop in obj) {puts(prop)};
return /bar/.test(obj.body); } ) )
The output from my print-stderr in this case is:
cstrom@whitefall:~/repos/fab$ node ./play/changes.js
status
headers
Ah! There is a reason that the argument is obj and not app—it might only contain the header response. So I adjust my filter to ignore the header and only return true on a "bar" type change:
( fab.filter ( function (obj) {
if (!obj.body) return false;

return /bar/.test(obj.body); } ) )
Now, when I update a bar document, I see:
cstrom@whitefall:~/repos/fab$ curl -n localhost:4011/changes/foo
{"seq":124,"id":"bar","changes":[{"rev":"1-967a00dff5e02add41819138abb3284d"}]}
{"seq":125,"id":"bar","changes":[{"rev":"2-a4b323f79cdc4ed3ce57b0f9145ea154"}]}
Changes to the "foo" document (or any other change) are ignored.

Day #84

2 comments:

  1. Chris - this is fascinating stuff. I've just started checking out fab as well and am having trouble getting my head around it :). Keep up the good work!

    Adam

    ReplyDelete
  2. I'm in much the same boat as you -- having trouble wrapping my brain about it :)

    But yah, this really is fascinating stuff. I think Jed may have really hit on something here. The more I play with it, the more I want to play with it. I had only planned on a day or two of this, but I may be playing with it for quite a while. Truly exciting stuff.

    ReplyDelete