Up today, I would like to explore code re-use of (fab) apps in the upcoming version 0.5 of fab.js. In my (fab) game, I have a dashboard resource that returns that list of players currently in the room:
(route, /^\/player_status/)Looking at this is the browser, I see:
( PRE )
( player_status )
() // PRE
() // route
Simple enough.
Now that I think about it though, I really prefer to see this from
curl
. It is nice to have it in HTML so I would just as soon not have to choose from one or the other. Aha! Code reuse opportunity!I create a new
/status
resource that produces a simple text response:( route, /^\/status/ )I can access that via
(undefined, {headers: { "Content-Type": "text/plain"}})
( player_status )
()
curl
and see:cstrom@whitefall:~/repos/my_fab_game$ curl http://localhost:4011/statusCool! Quick, dirty resuable (fab) apps are quick and easy to roll. But...
bob
fred
There is the problem of using two different routes to represent the same thing. I would much prefer requesting a single resource and inspectint
Accept
headers so that something like his would work:( route, /^\/status/ )For this, I will need to write a new (fab) app—
( accept, "text/html" )
( PRE )
( player_status )
()
()
(accept, "text/plain")
(undefined, {headers: { "Content-Type": "text/plain"}})
( player_status )
()
()
fab.accept
. I start as simple as possible:
fab.accept = function() {That is close to boiler-plate (fab) code for ternary apps. Like all (fab) apps, it returns a function (
function accept( write, mime_type ) {
return fab.stream( function( yes ) {
return fab.stream( function( no ) {
return write( function( write, head ) {
// console.log(inspect(head));
return ( head.headers.accept == mime_type ? yes : no )( write, head );
})();
});
});
}
return accept;
}();
accept()
) that also returns a function. To get the conditional branch, that function also returns a function. If the condition matches (e.g. the Accept
header matches), then the first application,denoted by the
yes
local variable, is executed. Otherwise, the no
application is executed (e.g. the next fab.accept
or a 404).I did have to use a
console.log()
(commented out), but only because I can never remember the attributes of the headers in fab.js / node.js. With that, I am ready to test fab.accept from the command line. There is no easy way to get curl to request plain text or HTML. Instead, I need to set the "Accept" HTTP header attribute with the -H
option:cstrom@whitefall:~/repos/my_fab_game$ curl -H "Accept: text/html" http://localhost:4011/statusNice, the HTML version of the resource is served up in response to "Accept: text/html". Can I get the plaint text version?
<pre>bob
fred
</pre>
cstrom@whitefall:~/repos/my_fab_game$ curl -H "Accept: text/plain" http://localhost:4011/statusNice!
bob
foo
I still have to polish off
fab.accept
(and it would be nice to have some tests), but that is a nice stopping point for the night. It is pretty cool that it so easy to write these little things!Day #230
No comments:
Post a Comment