Offend Me: code
Twitter RSS Feed

nosef

github, tarball

A set of nice wrapper functionality for quickly building web services with node.js.

nosef requires formidable which can be found via npm.

I've written a number of web servers in node.js that serve both html content and provide RESTish APIs and I wanted to put together a package of common functionality that I've find myself implementing slightly differently every time.

To that end I've pooled together all the useful bits of code I've written for various different web servers, tidied them up a bit and put them into a package that's available via npm.

The rest of what follows is from the README included in the package.

About

Nosef provides a couple of useful functions that wrap up some of the node http functionality and provide a simple mechanism for building web applications.

There are three main features:

The server

A nosef server simply listens on the chosen address and port for HTTP requests and calls handler functions based on URL patterns

To start a server, you call nosef.server, passing in a configuration object.

var nosef = require("nosef");
var server = nosef.server(config);

server is an instance of node's HTTP server with one additional event: "start" which is emitted when the server is started

config is a configuration object of the following format:

var config = {
    port: 8000, // Default: 80
    address: "127.0.0.1", // Default: "0.0.0.0",
    middleware: function(request, response) {
        console.log(request.url);
    },
    urls: [ // An array of arrays mapping URL patterns to handler functions
        ["/echo/{{path}}", echo_handler],
        ["/hello/{name}", hello_handler]
    ]
};

middleware is a function (or an array of functions) that take a request and a response object and can act upon them for every request even if there is no URL match. Examples of use could be logging, CSRF verification, authentication etc.

URL patterns are strings with optional variables that match against the path requested by a client. e.g. If you visit http://127.0.0.1:8000/echo/and/the/bunnymen/ in a browser, the path would be /echo/and/the/bunnymen.

Variables in URL patterns can take two forms:

Handlers

A handler is a function that takes a request, a response, and a parameters object as it's arguments. Nosef adds some convenience functions to the response object and parses GET, POST, and file upload data into the parameters object to save on the gruntwork.

To create a handler, pass a function into nosef.handler.

var echo_handler = nosef.handler(function(request, response, params) {
    response.write(params.path);
});

Params

The params object looks like:

{
    url: {}, // Variables from the URL patterm
    get: {}, // Query string parameters
    post: {}, // POST parameters
    request: {}, // get and post values combined
    files: {} // A map of uploaded file names to file objects
}

The file objects are created by formidable.

Response

The extensions to the response object are:

Convenience Handlers

Additionally, there are a couple of functions in nosef.handlers which serve as a convenience to quickly create handlers to do simple things. For example:

nosef.handlers.file("./media_folder", "path")

This will map a URL parameter called path (specify it in the URL pattern such as /media/{{path}}) and serve files from the local folder ./media_folder.

nosef.handlers.file("./robots.txt")

This will simply serve the contents of the file robots.txt to the URL it is bound to.

nosef.handlers.redirect("http://github.com", true);

This will redirect the client to http://github.com. The second parameter indicates whether the redirect is permanent or temporary; true for permanent.

You can use these convenience handlers in the place of a normal handler. For example:

var config = {
    urls: [
        ["/media/{{ path }}", nosef.handlers.file("./media_folder", "path")]
    ]
};

Templates

Nosef includes a simple system for reading and caching template files and then merging data into them before sending the result out to the client.

Templates are used by calling response.template from within a handler. Variables passed to response.template should be stored in an object and can be retrieved in the template using some very simple notation:

Property names of the object passed in should not contains spaces.

Variables

If you have a content object that looks like this:

var content = {
    foo: "This is foo",
    bar: {
        stool: "A bar stool",
        bar: "Black sheep",
        things: {
            i: "eye",
            four: 4
        }
    },
    array: ["first", "second", "third"]
}

You could use the following template to access them all:

Foo is "{{foo}}"
Bar:
    Stool: {{bar.stool}}
    Bar: {{bar.bar}}
    Things: {{bar.things.i}} and {{bar.things.four}}
Array:
    {{array.0}}, {{array.1}}, and {{array.2}}

Conditionals

There is also two very basic conditional blocks.

{% if bar.stool %}There is a bar stool!{% endif %}

This checks that there is a variable called bar.stool and if so, displays the content.

{% if not bar.stool %}There is no bar stool!{% endif %}

This does the opposite of 'if'.

Copying

See the COPYING file for more information

Example usage

var nosef = require("nosef");

var echo_handler = nosef.handler(function(request, response, params) {
    response.JSON(params);
});

var hello_handler = nosef.handler(function(request, response, params) {
    response.template("Hello {{who}}", params.url, "text/plain");
});

var config = {
    port: 8765,
    urls: [
        ["/echo/{{path}}", echo_handler],
        ["/hello/{who}", hello_handler]
    ]
};

nosef.server(config, function() {
    console.log("Server started");
}, function() {
    console.log("Server stopped");
});

See the examples folder for more examples

Tue, 02 Apr 2013 22:05:17 GMT - Permalink

blog comments powered by Disqus