Beeline
A laughably simplistic router for node.js
Currently works with node.js v0.3.1 and above
Goals
- Simple
- Unobtrusive
- Fairly Foolproof
- Easy to debug
- Fast
Examples
var bee = require("beeline");
var router = bee.route({
"/cheggit": function(req, res) {
},
"/names/`last-name`/`first-name`": function(req, res, tokens, values) {
},
"/static/`path...`": function(req, res, tokens, values) {
},
"/`user`/static/`path...`": function(req, res, tokens, values) {
},
"/blogs/`user-id: [a-z]{2}-\\d{5}`/`post-id: \\d+`": function(
req, res, tokens, values
) {
},
"r`^/actors/([\\w]+)/([\\w]+)$`": function(req, res, matches) {
},
"`404`": function(req, res) {
},
"`500`": function(req, res, err) {
}
});
router.add({
"/ /home r`^/index(.php|.html|.xhtml)?$`": function(req, res) {
},
"/my-method": {
"GET": function(req, res) {
},
"POST PUT": function(req, res) {
},
"any": function(req, res) {
}
},
"`405`": function(req, res) {
},
"/explicit-calls": function(req, res) {
if(url.parse(req.url).query["item-name"] === "unknown") {
return router.missing(req, res, this);
}
if(url.parse(req.url).query["item-name"] === "an-error") {
return router.error(req, res, err, this);
}
}
});
require("http").createServer(router).listen(8001);
See test/test.js
for a working example.
The API
To start, simply store the beeline
library in a local variable:
var bee = require("beeline");
The beeline
library contains the following three methods:
-
bee.route(routes)
: Used to create a new router. It returns a function called rtn_fn
that takes ServerRequest and ServerResponse objects as parameters. The routes
parameter is an objects that maps rules to handlers. See examples section for more details.
-
bee.staticFile(path, mimeType[, maxage=31536000])
: This is a utility method that is used to quickly expose static files. It returns a function called rtn_fn
that takes ServerRequest and ServerResponse objects as parameters. When rtn_fn
is called, the file contents located at path
are served (via the ServerResponse) with the Content-Type
set to the mimeType
parameter. If the file at path
does not exist a 404
is served. The optional maxage
parameter is used to in the response's Cache-Control
header. Also note that all Set-Cookie
headers are removed. Here's an example of how you might use bee.staticFile
:
bee.route({
"/robots.txt": bee.staticFile("./content/robots.txt", "text/plain")
});
-
bee.staticDir(path, mimeTypes[, maxage=31536000])
: This is utility method is used to expose directories of files. It returns a function called rtn_fn
that takes a ServerRequest object, a ServerResponse object, an optional third parameter, and an array of strings called matches
as parameters. Whenever rtn_fn
is called, the items of matches
are joined together and then concatenated to path
. The resulting string is assumed to be a path to a specific file. If this file exists, its contents are served (via the ServerResponse) with the Content-Type
set to the value that corresponds to the file's extension in the mimeTypes
object. If the resulting string doesn't point to an existing file or if the file's extension is not found in mimeTypes
, then a 404
is served. Also, file extensions require a leading period (.
) and are assumed to be lowercase. The optional maxage
parameter is used to in the response's Cache-Control
header. Also note that all Set-Cookie
headers are removed. Here's an example of how you might use bee.staticDir
:
bee.route({
"r`^/pics/(.*)$`": bee.staticDir(
"./content/pics/",
{
".gif": "image/gif", ".png": "image/png",
".jpg": "image/jpeg", ".jpeg": "image/jpeg"
}
),
"/static/`path...`": bee.staticDir(
"./static/",
{
".txt": "text/plain", ".html": "text/html",
".css": "text/css", ".xml": "text/xml"
}
),
"/`user`/img-library/`path...`": bee.staticDir(
"./user-images/", { ".jpg": "image/jpeg", ".jpeg": "image/jpeg" }
)
});
Beeline is also at least somewhat compatibile with expressjs. Here's an example:
app.use(beeline.route({
"/": function(req, res, next) {
fs.readFile("./templates/index.html", function(err, data) {
if(err) { throw err; }
res.html(data);
});
},
"/`user`/static/`path...`": function(req, res, tokens, values, next) {
}
}));
Note the next
callback is always passed as the last parameter.
Precedence Rules
In the event that a request matches two rules, the following precedence rules are considered:
- Fully defined rules take highest precedence. In other words,
"/index"
has a higher precedences then "r`^/index$`"
even though semantically both rules are exactly the same.
- Tokens and RegExp rules have the same precedence
- RegExp rules take higher precedence than
404
404
and 405
have the lowest precedences
- The
500
rules is outside the precedence rules. It can potentially be triggered at any time.
- Amoung request methods, "any" has the lowerest precdence. Also note that the "x-http-method-override" header is respected.
If the exact same rule is defined twice, then it's unspecified which request handler will be triggered.
Getting Beeline
The easiest way to get beeline is with npm:
npm install beeline
Alternatively you can clone this git repository:
git clone git://github.com/xavi-/beeline.git
Running Unit Tests
Execute the following commands to run the beeline's unit tests:
$ cd <beeline-directory>
$ cd test
$ node test.js
The last line printed to the console should be, "All done. Everything passed.", if all the tests passed successfully.
Developed by
License
This project is released under The MIT License.