Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

A simple http server for node.js that has sinatra like qualities. Ideal for generating web services via node.

tree: 7808b7a3d5

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 lib
Octocat-spinner-32 README.markdown
Octocat-spinner-32 hello_world.js Allow simple sync responses for html (strings) and json (objects). March 26, 2010
Octocat-spinner-32 memresourced.js
Octocat-spinner-32 package.json
Octocat-spinner-32 tasks.db
Octocat-spinner-32 todos_backend.js
README.markdown

node-router

Node-router is a small simple node.js http server that makes building simple web-services super simple.

Node libraries

There are two ways to include this library in your node project. You can either copy the node-router.js file in the same directory as your script and require it with a relative path:

var server = require('./node-router');

Or you can copy node-router.js to somewhere in your require.paths array. Then you can use a global require like:

var server = require('node-router');

See the node docs for more details.

Hello World example

This example has a single get route that returns the string hello world. If there is path after the root, it will be put in place of hello world.

var server = require('node-router');

function hello(req, res, match) {
  res.simpleHtml(200, "Hello " + (match || "World") + "!");
}

server.get(new RegExp("^/(.*)$"), hello);
server.listen(8080);

RESTful Resources made easy

server.resource maps a group of the common routes for a RESTful resource. There is also a controller generator that makes building a simple in-memory data controller easy.

var server = require('node-router');

var people = [
    { name: "Bob", age: 47, programmer: false },
    { name: "Tim", age: 27, programmer: true },
    { name: "Jack", age: 3, programmer: false}
];

function on_change(id) {
    node.debug(id, JSON.stringify(people[id]));
}

server.resource("people", server.resourceController("people", people), on_change);
server.listen(8080);

Backend for SproutCore Todos example application.

This is a node.js backend for the Todos example in the SproutCore documentation. http://wiki.sproutcore.com/Todos+01-Create+Your+SproutCore+Application

// This is a sample backend for the SproutCore todos demo using node-router.
// It uses an in-memory data store and writes it to disk on change
// for persistance.
// This provides the same REST style api as the merb example and even hosts
// on port 4000. It's a drop in replacement for the sample merb backend.

var server = require('node-router');

var tasks;

// Simple utility that allows mapping over any object
// as if it were a hash.  Calls fn(key, value) for each pair.
Object.prototype.map_pairs = function (fn) {
    var accum = [];
    for (key in this) {
        if (this.hasOwnProperty(key)) {
            accum.push(fn(key, this[key]));
        }
    }
    return accum;
};

// Convert raw data to part of REST response
function json_for_task(id, task) {
    task = task || {};
    return {
        guid: "/tasks/" + id,
        description: task.description,
        order: task.order,
        isDone: task.is_done
    };
}

function apply_json_to_task(task, json_hash) {
  task.description = json_hash['description'];
  task.order = json_hash['order'];
  task.is_done = json_hash['isDone'];
}

// Serialize the data to the disk
function save_data() {
  var fd = node.fs.open("tasks.db", node.O_WRONLY, 0666).wait();
  node.fs.write(fd, JSON.stringify(tasks)).wait();
  node.fs.close(fd).wait();
}

// Load the data from the disk
function load_data(callback) {
    // Load the database from disk
    var promise = node.fs.cat("tasks.db", "utf8");
    promise.addCallback(function (json) {
        tasks = JSON.parse(json);
        callback(true);
    });
    promise.addErrback(function () {
        tasks = [];
        callback(false);
    });
}

// This handles the REST requests and generates the responses
var tasksController = {
    index: function (req, res) {
        res.simpleJson(200, {content: tasks.map_pairs(json_for_task), self: '/tasks'});
    },
    show: function (req, res, id) {
        var task = tasks[id];
        if (task) {
            res.simpleJson(200, {content: json_for_task(id, task), self: '/tasks/' + id});
        } else {
            res.notFound();
        }
    },
    create: function (req, res) {
        req.jsonBody(function (json) {
            var task = {}, id, url;
            json = json && json.content;
            if (!json) {
                res.notFound();
            } else {
                apply_json_to_task(task, json);
                id = tasks.length + 1;
                tasks[id] = task;
                tasks.length += 1;
                save_data();
                url = "/tasks/" + id;
                res.simpleJson(201, {content: json_for_task(id, task), self: url}, [["Location", url]]);
            }
        });
    },
    update: function (req, res, id) {
        puts("Update");
        req.jsonBody(function (json) {
            var task = {}, new_id, url;
            json = json && json.content;
            if (!json) {
                res.notFound();
            } else {
                apply_json_to_task(task, json);
                tasks[id] = task;
                save_data();
                res.simpleJson(200, {content: json_for_task(id, task), self: "/tasks/" + id});
            }
        });
    },
    destroy: function (req, res, id) {
        delete(tasks[id]);
        save_data();
        res.simpleJson(200, "200 Destroyed");
    }
};

// Mount our controller as a RESTful resource
server.resource('tasks', tasksController);

// Load the datastore
puts("Loading data from file...");
load_data(function (success) {
    // Kickoff the server
    if (success) {
        puts("Loaded");
    } else {
        puts("Error, creating empty tasks array");
        save_data();
    }
    // And start the server when done
    server.listen(4000);
});
Something went wrong with that request. Please try again.