Permalink
Browse files

update readme

  • Loading branch information...
1 parent 3b79aab commit dcc570e803e99b91980796d2183aa10165cd7871 Carlos Rodriguez committed Jan 10, 2013
Showing with 144 additions and 49 deletions.
  1. +144 −49 README.md
View
193 README.md
@@ -12,7 +12,7 @@ middler is a flexible, tiny middleware runner for Node.js which can easily be
embedded in an existing http server or even an existing middleware chain.
Also provided is [express](https://github.com/visionmedia/express)-like routing
and [union](https://github.com/flatiron/union) compatibility. Best of all, the
-code is dead simple and dependency-free.
+code is readable, compact, tested, benchmarked, MIT-licensed, and dependency-free.
Enjoy!
@@ -29,71 +29,70 @@ Basic usage
```javascript
var middler = require('middler')
, server = require('http').createServer()
- , buffet = require('buffet')('./public')
+// to attach a single handler to the server:
+middler(server, function (req, res, next) {
+ console.log(req.method, req.url);
+ next();
+});
+
+// calling middler(server) again will access the same middleware chain:
middler(server)
- .add(buffet)
- .add(function(req, res, next) {
- // ... do some stuff
- next();
+ // note: all methods are chainable!
+ .get('/', function(req, res, next) {
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+ res.end('hello world!');
+ })
+ // since this handler is added last, it will run last:
+ .add(function (req, res, next) {
+ res.writeHead(404, {'Content-Type': 'text/plain'});
+ res.end('page not found...');
})
- .add(buffet.notFound);
server.listen(3000);
```
-Routing
--------
+HTTP Routing
+------------
+
+It's easy to set up routes which will respond to certain methods and paths:
```javascript
middler(server)
+ .add('/', function (req, res, next) {
+ // handle any request to "/" path
+ })
.get('/robots.txt', function (req, res, next) {
+ // handle GET requests only
res.end('humans only!');
})
+ .first('/posts/*', function (req, res, next) {
+ // do some setup for any path starting with '/posts/'
+ next();
+ })
.post('/posts/:id', function (req, res, next) {
// req.params.id available
- });
-```
-
-Multiple paths/methods/handlers
--------------------------------
-
-```javascript
-middler(server)
- .add(['get', 'post'], '/', function (req, res, next) {
- // handle both get and post requests
- });
-
-// Or add multiple handlers
-function bodyParser (req, res, next) { req.body = ... }
-function formHandler (req, res, next) { use req.body ... }
-
-middler(server)
- .post('/posts', [bodyParser, formHandler]);
-```
-
-Alternate attach syntax
------------------------
-
-```js
-var server = require('http').createServer();
-var m = middler()
- .add(function (req, res, next) {
- // handle request...
})
- .attach(server);
+ .put('/articles/*/*', function (req, res, next) {
+ // req.params is an array with 2 elements
+ })
+```
-// you can also detach!
-m.detach();
+Tips:
-// m can be attached do a different server now
-```
+- Paths must be either strings starting with `/`, or RexExp objects.
+- Other methods available: `delete`, `head`, `patch`
middler is a middleware, too
----------------------------
-Writing some middleware and need routes? Build your middler chain up and return
-`middler().handler`, which itself acts as a middleware!
+Now, the coolest feature of middler which sets it apart from the rest:
+embeddability.
+
+Each middler instance has a `handler` property which allows you to use the entire
+chain as a single middleware handler!
+
+Example with [connect](https://github.com/senchalabs/connect):
```javascript
var connect = require('connect')
@@ -121,16 +120,112 @@ var app = connect()
http.createServer(app).listen(3000);
```
+This can be extremely useful if you want to:
+
+- Bundle your app's features as middler chains which can be optionally attached
+ to the main chain, similar to "controllers" in MVC language.
+- Create a vhost architecture which hands off requests to a sub-chain.
+- Write node modules which provide advanced middleware (respond to a variety
+ of methods/paths/etc), and can be attached directly to a server instance or
+ used with connect/express/flatiron.
+
+Stack control
+-------------
+
+To add handlers which should run first or last in the stack:
+
+```js
+middler(server)
+ .last(function (req, res, next) {
+ // this should run last (weight = 1000)
+ })
+ .first(function (req, res, next) {
+ // this should run first (weight = -1000)
+ })
+ .add(500, function (req, res, next) {
+ // numbers become weights -- give an arbitrary weight of 500, will run in-
+ // between the above handlers
+ })
+```
+
+To remove handler(s) from the stack:
+
+```js
+function myHandler (req, res, next) {}
+
+middler(server)
+ .add(myHandler)
+ .add('/about', function (req, res, next) {
+ res.end('about us');
+ })
+ .add(function (req, res, next) {
+ res.end('page not found');
+ })
+
+// let's remove myHandler
+middler(server).remove(myHandler);
+
+// let's remove /about
+middler(server).remove('/about');
+
+// actually let's clear the whole thing
+middler(server).removeAll();
+```
+
+Multiple paths/methods/handlers
+-------------------------------
+
+```javascript
+middler(server)
+ .add(['get', 'post'], '/', function (req, res, next) {
+ // handle both GET and POST requests to "/"
+ })
+
+// Or add multiple handlers
+function bodyParser (req, res, next) { req.body = ... }
+function formHandler (req, res, next) { // do something with req.body ... }
+
+middler(server)
+ .post('/posts', [bodyParser, formHandler])
+```
+
+When multiple handlers are added, they execute in series when the other
+conditions match.
+
Handling errors
---------------
As of v0.5.0, middler is an EventEmitter, and will emit an `error` event (if
you listen for it).
-- If there is no `error` listener, middler will terminate the response with a `500
-Internal Server Error` status and no body. The error and stack trace will be printed
-to `process.stderr`.
-- If there are `error` listener(s), they will be passed `err, req, res`.
+- If there are `error` listener(s), they will be invoked with `err, req, res`
+ and the error will not propagate further.
+- If there is no `error` listener:
+ - In the case of an embedded middler (`middler().handler` as in the above
+ section), the error will be passed to the parent chain, i.e. `next(err)`.
+ - Otherwise, the default error handler will run which terminates the response
+ with `500 Internal Server Error` status and no body. The error and stack
+ trace will be printed to `process.stderr`.
+
+
+Alternate attach syntax
+-----------------------
+
+```js
+var server = require('http').createServer();
+var router = middler()
+ .add(function (req, res, next) {
+ // handle request...
+ })
+ .attach(server)
+
+// you can also detach!
+router.detach();
+
+// router can be attached do a different server now
+```
+
+------------
[union](https://github.com/flatiron/union) compatibility
--------------------------------------------------------
@@ -141,7 +236,7 @@ middler(server)
// this.req
// this.res
this.res.emit('next');
- });
+ })
```
Benchmarks

0 comments on commit dcc570e

Please sign in to comment.