Web development/model-router

From ISoft Wiki
< Web development
Revision as of 16:25, 19 February 2013 by Duff (talk | contribs) (moar)
Jump to navigationJump to search

model-router does a few things that make writing data servers easier:

  • Routing
  • Session handling/state
  • Wrapping up authentication
  • Checking for parameters existence

Including

You could have multiple router-things if you wanted to - you know, in case you were running multiple sites from the same node.js server, or something - but for your purposes you'll probably just want to instantiate one.

var Router = require('model-router')
var router = new Router()

It doesn't launch any servers of its own, that would be rude. You'll want to create your own server in the usual way, and then tell model-router to handle it if appropriate.

model-router only sends back JSON responses, and doesn't do anything with static content out of the box, so if you want to serve HTML/JavaScript files or something, you'll have to do it yourself:

require('http').createServer(function(req, res) {
	var pathname = require('url').parse(req.url).pathname
	var match
	if (match = /^\/static(\/.*)$/.exec(pathname)) {
		require('send')(req, match[1]).root('./static/').pipe(res)
	} else {
		router.handleRequest(req, res)
	}
}).listen(8080)

Routing

All right, your server is running. You want to add a new response to certain messages - so that requests to yourdomain.com/information/time would get the current server time back, or something dumb like that.

router.route('/information/time', function(parameters, session, next) {
	next(new Date())
})

Browsing to the URL should immediately get you back this response:

{"success":true,"output":"2013-02-19T22:00:56.507Z"}

But let's say that something bad happens on the server - maybe it's an error if a client asks for the server time on a Sunday. You could reflect that by rewriting the function like so:

router.route('/information/time', function(parameters, session, next) {
	var date = new Date()
	if (date.getDay() === 0) {
		next(new Error("Don't bother me on Sunday!"))
	} else {
		next(date)
	}
})

Visiting that same URL on a Sunday would get you this response instead:

{"success":false,"message":"Don't bother me on Sunday!"}

In realistic scenarios, you'll probably want to only respond with errors in the case of legitimate server errors, like a query failing or a missing file or something.

Session state

All right, so you can easily fling data back to the client. Unbeknownst to you (before you read this sentence), it turns out that model-router also stores a session variable for each visitor (using a cookie that it sets on the client)! You can set parameters on this object whenever you like, and access them again later:

router.route('/counter/increment', function(parameters, session, next) {
	session.counter = (session.counter || 0) + 1
	next()
})

But now let's say that you want to see the current value of that pointless counter! But let's use a new feature that I feel like telling you about: guaranteed parameters. Like, you know, where a request is only valid if a certain value is provided? You could do a bunch of input parsing, and check to see if certain values were defined or whatnot, but model-router handles some of that for you.

Let's only give back the current value if the user provides a parameter called "please" - we won't even bother to check what it is, as long as it's set:

router.route('/counter/value', function(parameters, session, next) {
	next(session.counter || 0)
}, ['please'])

If you don't pass in a parameter with the request (either as part of the query string in the URL, or in the headers), you'll get back this response:

{"success":false,"message":"You must provide these parameters: please","code":"MISSING_PARAMETERS"}