Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

use fab for serving api requests

  • Loading branch information...
commit 986c96e643abfbd73fd69aa3602cc483c10813e2 1 parent 03547de
@technoweenie authored
Showing with 100 additions and 127 deletions.
  1. +2 −1  README.md
  2. +75 −93 lib/api.js
  3. +23 −33 test/api_test.js
View
3  README.md
@@ -4,11 +4,12 @@ Track what users are on which pages with redis.
## Installation
-Depends on ntest, redisclient, and underscore.
+Depends on fab, ntest, redisclient, and underscore.
There's no packaging system for node.js yet, so I've just been creating symlinks
in my `~/.node_libraries` path.
+ $ ln -s /path/to/fab ~/.node_libraries/fab
$ ln -s /path/to/redisclient ~/.node_libraries/redisclient
$ ln -s /path/to/underscore ~/.node_libraries/underscore
$ ln -s /path/to/wheres-waldo/lib ~/.node_libraries/wheres-waldo
View
168 lib/api.js
@@ -1,6 +1,7 @@
var Query = require('querystring'),
Http = require('http'),
Url = require('url'),
+ fab = require('fab')
sys = require('sys')
// higher level method if you don't want to worry about setting up the waldo
@@ -22,12 +23,77 @@ exports.createServer = function(waldo) {
// * list(location, users)
// * track()
//
-function ApiServer(waldo) {
- var apiServer = this
+function ApiServer(waldo, prefix) {
+ if(!prefix)
+ prefix = '/waldo'
this.waldo = waldo
- this.server = Http.createServer(function(req, res) {
- new ApiRequest(apiServer, req, res)
- })
+
+ app = ( fab )
+ app = this.mountToFab(prefix, app)
+ this.server = Http.createServer(app(fab));
+}
+
+ApiServer.headers = {'Content-Type': 'application/json'}
+ApiServer.prototype.mountToFab = function(prefix, fab) {
+ var app = this
+ return ( fab )
+ (prefix)
+ ('/track_and_list', function(respond) {
+ var fab = this
+ if(!fab.url.query) fab.url.query = {}
+ if(fab.url.query.name && fab.url.query.location) {
+ app.waldo.track(fab.url.query.name, fab.url.query.location).addCallback(function() {
+ app.waldo.list(fab.url.query.location).addCallback(function(users) {
+ respond(app.buildJSON(users, fab))
+ respond(null)
+ })
+ })
+ } else {
+ return app.buildJSON("", fab)
+ }
+ })
+ ('/locate', function(respond) {
+ var fab = this
+ if(!fab.url.query) fab.url.query = {}
+ if(fab.url.query.name) {
+ app.waldo.locate(fab.url.query.name).addCallback(function(location) {
+ respond(app.buildJSON(location, fab))
+ respond(null)
+ })
+ } else {
+ return app.buildJSON(null, fab)
+ }
+ })
+ ('/list', function(respond) {
+ var fab = this
+ if(!fab.url.query) fab.url.query = {}
+ if(fab.url.query.location) {
+ app.waldo.list(fab.url.query.location).addCallback(function(users) {
+ respond(app.buildJSON(users, fab))
+ respond(null)
+ })
+ } else {
+ return app.buildJSON(null, fab)
+ }
+ })
+ ('/track', function(respond) {
+ var fab = this
+ if(!fab.url.query) fab.url.query = {}
+ if(fab.url.query.name && fab.url.query.location) {
+ app.waldo.track(fab.url.query.name, fab.url.query.location).addCallback(function() {
+ respond(app.buildJSON(true, fab))
+ respond(null)
+ })
+ } else {
+ return app.buildJSON(false, fab)
+ }
+ })
+
+ .GET(function() {
+ return [404, ApiServer.headers, "Not found."]
+ })
+ [404]("Not found.")
+ ();
}
ApiServer.prototype.addListener = function(event, listener) {
@@ -50,93 +116,9 @@ ApiServer.prototype.close = function() {
return this.server.close()
}
-function ApiRequest(server, req, res) {
- this.url = Url.parse(req.url)
- this.server = server
- this.waldo = server.waldo
- this.req = req
- this.res = res
- this.params = this.url.query ? Query.parseQuery(this.url.query) : {}
-
- switch(this.url.pathname) {
- case '/track_and_list':
- this.track_and_list()
- break
-
- case '/locate':
- this.locate()
- break
-
- case '/list':
- this.list()
- break
-
- case '/track':
- this.track()
- break
-
- default:
- this.waldo.emit('request', req, 404)
- this.res.sendHeader(404)
- this.res.sendBody("Not found.")
- this.res.finish()
- }
-}
-
-ApiRequest.prototype.locate = function() {
- var api = this
- if(this.params.name) {
- this.waldo.locate(this.params.name).addCallback(function(location) {
- api.respond(location)
- })
- } else {
- api.respond()
- }
-}
-
-ApiRequest.prototype.track_and_list = function() {
- var api = this
- if(this.params.name && this.params.location) {
- this.waldo.track(this.params.name, this.params.location).addCallback(function() {
- api.waldo.list(api.params.location).addCallback(function(users) {
- api.respond(users)
- })
- })
- } else {
- api.respond()
- }
-}
-
-ApiRequest.prototype.list = function() {
- var api = this
- if(this.params.location) {
- this.waldo.list(this.params.location).addCallback(function(users) {
- api.respond(users)
- })
- } else {
- api.respond()
- }
-}
-
-ApiRequest.prototype.track = function() {
- var api = this
- if(this.params.name && this.params.location) {
- this.waldo.track(this.params.name, this.params.location).addCallback(function() {
- api.respond(true)
- })
- } else {
- api.respond(false)
- }
-}
-
-ApiRequest.headers = {'Content-Type': 'application/json'}
-ApiRequest.prototype.respond = function(body) {
+ApiServer.prototype.buildJSON = function(body, fab) {
body = JSON.stringify(body == null ? '' : body)
- if(this.params.callback)
- body = this.params.callback + "(" + body + ")"
-
- this.waldo.emit('request', this.req, 200)
- this.res.sendHeader(200, ApiRequest.headers)
- this.res.sendBody(body)
- this.res.finish()
+ if(fab.url.query.callback)
+ body = fab.url.query.callback + "(" + body + ")"
+ return body
}
View
56 test/api_test.js
@@ -23,55 +23,55 @@ waldoServer.server.addListener('close', function(e) {
before(function() { redis.flushdb().wait() })
it("cannot locate missing user", function() {
- var resp = client.request("/locate?name=bob").wait();
+ var resp = client.request("/waldo/locate?name=bob").wait();
assert.equal('""', resp.body);
})
it("lists empty location", function() {
- var resp = client.request("/list?location=gym").wait();
+ var resp = client.request("/waldo/list?location=gym").wait();
assert.equal('[]', resp.body);
})
it("tracks user's location", function() {
- client.request("/track?name=bob&location=gym").wait()
- var resp = client.request("/locate?name=bob").wait();
+ client.request("/waldo/track?name=bob&location=gym").wait()
+ var resp = client.request("/waldo/locate?name=bob").wait();
assert.equal('"gym"', resp.body);
- var resp = client.request("/list?location=gym").wait();
+ var resp = client.request("/waldo/list?location=gym").wait();
assert.equal('["bob"]', resp.body);
})
it("tracks a user and lists users for that location", function() {
- client.request("/track?name=thing1&location=hat").wait()
- var resp = client.request("/track_and_list?name=thing2&location=hat").wait()
+ client.request("/waldo/track?name=thing1&location=hat").wait()
+ var resp = client.request("/waldo/track_and_list?name=thing2&location=hat").wait()
assert.equal('["thing1","thing2"]', resp.body)
})
it('handles bad 404 requests', function() {
- var resp = client.request("/").wait()
+ var resp = client.request("/waldo").wait()
assert.equal(404, resp.statusCode)
})
it('ignores invalid locate request', function() {
- var resp = client.request("/locate").wait();
+ var resp = client.request("/waldo/locate").wait();
assert.equal('""', resp.body);
})
it('ignores invalid list request', function() {
- var resp = client.request("/list").wait();
+ var resp = client.request("/waldo/list").wait();
assert.equal('""', resp.body);
})
it('ignores invalid track_and_list request', function() {
- var resp = client.request("/track_and_list").wait();
+ var resp = client.request("/waldo/track_and_list").wait();
assert.equal('""', resp.body);
})
it('ignores invalid track request', function() {
promise = promises.group(
- client.request("/track"),
- client.request("/track?name=1"),
- client.request("/track?location=1"))
+ client.request("/waldo/track"),
+ client.request("/waldo/track?name=1"),
+ client.request("/waldo/track?location=1"))
var resps = promise.wait()
resps.forEach(function(resp) {
assert.equal('false', resp.body)
@@ -79,64 +79,54 @@ it('ignores invalid track request', function() {
})
it('wraps locate request in callback', function() {
- var resp = client.request("/locate?callback=foo").wait();
+ var resp = client.request("/waldo/locate?callback=foo").wait();
assert.equal('foo("")', resp.body);
})
it('wraps list request in callback', function() {
- var resp = client.request("/list?callback=foo").wait();
+ var resp = client.request("/waldo/list?callback=foo").wait();
assert.equal('foo("")', resp.body);
})
it('wraps track_and_list request in callback', function() {
- var resp = client.request("/track_and_list?callback=foo").wait();
+ var resp = client.request("/waldo/track_and_list?callback=foo").wait();
assert.equal('foo("")', resp.body);
})
it('wraps track request in callback', function() {
- var resp = client.request("/track?callback=foo").wait();
+ var resp = client.request("/waldo/track?callback=foo").wait();
assert.equal('foo(false)', resp.body);
})
-it('emits request event', function() {
- promise = listeners.wrap(waldoServer, 'request', function(r, s) {
- assert.equal('/foo', r.url)
- assert.equal(404, s)
- promise.emitSuccess()
- })
- client.request("/foo")
- promise.wait()
-})
-
it('emits track event', function() {
promise = listeners.wrap(waldoServer, 'track', function(user, location) {
assert.equal('mark', user)
assert.equal('work', location)
promise.emitSuccess()
})
- client.request("/track?name=mark&location=work")
+ client.request("/waldo/track?name=mark&location=work")
promise.wait()
})
it('emits locate event', function() {
- client.request("/track?name=mark&location=work")
+ client.request("/waldo/track?name=mark&location=work")
promise = listeners.wrap(waldoServer, 'locate', function(user, location) {
assert.equal('mark', user)
assert.equal('work', location)
promise.emitSuccess()
})
- client.request("/locate?name=mark")
+ client.request("/waldo/locate?name=mark")
promise.wait()
})
it('emits list event', function() {
- client.request("/track?name=mark&location=work")
+ client.request("/waldo/track?name=mark&location=work")
promise = listeners.wrap(waldoServer, 'list', function(location, users) {
assert.equal('mark', users[0])
assert.equal('work', location)
promise.emitSuccess()
})
- client.request("/list?location=work")
+ client.request("/waldo/list?location=work")
promise.wait()
})
Please sign in to comment.
Something went wrong with that request. Please try again.