npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

routes-http

v0.5.0

Published

Simple but powerful HTTP request router

Downloads

15

Readme

Synopsis

routes-http is a simple HTTP request router for node.js based on routes.

stability 2 - unstable license - Unlicense

Build Status Coverage Status Dependencies

NPM status

Features

Simple but powerful

routes-http is just a thin wrapper around routes. This means if you've used routes or routes-based routers before, you can start using routes-http right away:

var routes = require('routes-http')();
routes.addRoute('/foo/:arg/*', function(req, res, opts) {
    console.log(opts);
});
// … more code …
req.url = '/foo/bar/qux/baz';
routes(req, res);
/*
{
    params: {arg: 'bar'},
    splats: ['qux/baz']
}
*/

Chaining API

You can create a router and add all your routes in a single line. No more repeating yourself! The following is perfectly valid:

var routes = require('routes-http')()
    .addRoute('/foo', function(req, res) {/* … */})
    .addRoute('/bar', function(req, res) {/* … */})
    .addRoute('/qux', function(req, res) {/* … */});
// … more code …
routes(req, res);

Or simply:

var routes = require('routes-http')().addRoutes({
    '/foo': function(req, res) {/* … */},
    '/bar': function(req, res) {/* … */},
    '/qux': function(req, res) {/* … */}
});

Semantic error-handling

routes-http uses httperr for its own errors and allows you to provide an error handler that will be used for all errors, including matching errors:

var routes = require('routes-http')();
routes.addRoute('/foo', function(req, res) {/* … */});
// … more code …
req.url = 'http://localhost/foo';
routes(req, res, function(err) {
    console.error(err);
});
/*
{ [NotFound]
    title: 'Not Found',
    name: 'NotFound',
    code: 'NOT_FOUND',
    statusCode: 404
}
*/

Pain-free nesting

Want to use a separate router for each namespace of your app? No problem. Nesting routes is as simple as defining normal routes. They don't even need to know about each other or that they are nested in order to work:

var router = require('routes-http'),
    routes = router(),
    childRoutes = router();

routes.addRoute('/hello/', childRoutes); // Always use a trailing slash!
childRoutes.addRoute('/world', function(req, res) {
    res.end('Hello from /hello/world !');
});

HTTP method dispatching

Want to have different views for each HTTP method? Just specify an object instead of a function:

var routes = require('routes-http')();
routes.addRoute('/foo', {
    GET: function(req, res) {res.end('You used GET');},
    POST: function(req, res) {res.end('You used POST')}
});

/* … more code … */

routes(req, res, function(err) {
    if (err.statusCode === 405) {
        res.writeHead(err.statusCode, err.title, {'Allow': err.allowed.join(', ')});
        res.write('You used ' + req.method + '\n');
        res.write('Allowed methods: ' + err.allowed.join(', ') + '\n');
    } else {
        res.writeHead(err.statusCode, err.title);
    }
    res.end(err.statusCode + ' ' + err.title);
});
$ curl http://localhost:8000/foo
You used GET
$ curl -X POST http://localhost:8000/foo
You used POST
$ curl -X DELETE http://localhost:8000/foo
You used DELETE
Allowed methods: GET, POST
405 Method Not Allowed

Minimalistic requirements

Want to use the router without passing in request and response objects? You can do that.

var routes = require('routes-http')();
routes.addRoute('/foo', function() {/* … */});
routes({url: 'http://localhost/foo'}); // Works!
routes('/foo'); // Also works!
var routes = require('routes-http')();
routes.addRoute('/foo', function(url, data) {/* … */});
routes('/foo', {proprietary: 'data-structure'}); // Works!

Basic Usage Example

var router = require('routes-http'),
    http = require('http'),
    routes = router();

routes.addRoute('/hello/world', function(req, res) {
    res.end('Hello world!');
});
routes.addRoute('/throws', function(req, res) {
    throw new Error();
});

http.createServer(function(req, res) {
    routes(req, res, function(err) {
        if (err.statusCode && err.title) {
            res.writeHead(err.statusCode, err.title);
            res.end(err.statusCode + ' ' + err.title);
        } else {
            res.writeHead(500, 'Internal Server Error');
            res.end('An error occurred');
        }
    });
}).listen(8000);
$ curl http://localhost:8000/hello/world
Hello World!
$ curl http://localhost:8000/does/not/exist
404 Not Found
$ curl Http://localhost:8000/throws
An error occurred

Install

With NPM

npm install routes-http

From source

git clone https://github.com/pluma/routes-http.git
cd routes-http
npm install
make test

API

routes(req, [res], [handleError:Function])

Resolves the given request and invokes the matching view if possible.

If the route can not be resolved, a 404 Not Found error will be raised.

If a handleError function is passed, the function will be called with the Error object if an error is thrown by the view or the route resolution fails.

The matched view will be invoked with the following arguments:

req

The original request.

res

The original response.

opts

An object with two properties:

opts.params

An object containing the matched route params. For child routes, the object will contain params matched by their parent routes as well, but child routes will take precedence over parent routes when params are named identically.

Example:

childRoutes.addRoute('/:foo', function(req, res, opts) {/* … */});
routes.addRoute('/:foo/', childRoutes);
routes({url: '/qux/bar'}); // opts.params = {'foo': 'bar'}

opts.splats

An array containing the matched route splats. For child routes, the array will contain splats matched by their parent routes as well, with child routes' splats appearing at the end of the array.

Example:

childRoutes.addRoute('/*', function(req, res, opts) {/* … */});
routes.addRoute('/*/foo/', childRoutes);
routes({url: '/qux/foo/bar'}); // opts.splats = ['qux', 'bar']

routes.addRoutes({path: view})

Invokes routes.addRoute for each key/value pair.

Note that because JavaScript object key order can not be guaranteed this is not recommended if you have paths that depend on the resolution order.

Example:

The following may produce inconsistent results:

routes.addRoutes({
    '/:foo/': function(req, res, opts) {/* … */},
    '/:bar/': function(req, res, opts) {/* … */}
});

routes.addRoutes([[path:String, view]])

Invokes routes.addRoute for each pair of path and view in the given array.

routes.addRoute(path:String, view:Function)

Adds a route with the given path. The route will resolve to the given function, invoking it when the route is matched.

routes.addRoute(path:String, view:Object)

Adds a route with the given path. The object is expected to have methods named after the HTTP methods supported by the view that will be invoked when the route is matched with the respective HTTP method.

If the route is resolved, but the view object has no matching property for the request's HTTP method, a 405 Method Not Allowed error will be raised with an array containing the names of the supported HTTP methods as its allowed property.

Example:

routes.addRoute('/foo/bar', {
    GET: function(req, res) { // Always use uppercase!
        res.end('You have sent a GET request.');
    },
    POST: function(req, res) {
        res.end('You have sent a POST request');
    }
});

routes.addRoute(path:String, view:routes)

Adds a route with the given path prefix. When the route is matched, the prefix will be replaced by a slash and the resulting URL will be passed to the given routes function.

Example:

childRoutes.addRoute('/bar', function(req, res) {
    res.end('You have accessed /foo/bar !');
});
childRoutes.addRoute('/', function(req, res) {
    res.end('You have accessed /foo/ !');
});
routes.addRoute('/foo/', childRoutes); // Always use a trailing slash!

Unlicense

This is free and unencumbered public domain software. For more information, see http://unlicense.org/ or the accompanying UNLICENSE file.