Journeyを使ったルーティング

Journey
liberal JSON-only HTTP request routing for node.

createServer

基本的なサーバを作る。

/**
 * server.js
 */
var http = require('http');

http.createServer(function(req, res) {
  req.on('end', function() {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('welcome');
  });
}).listen(3000);

console.log('Server running at http://127.0.0.1:3000');


http-consoleで確認。

% http-console http://localhost:3000
> http-console 0.6.0
> Welcome, enter .help if you're lost.
> Connecting to localhost on port 3000.

http://localhost:3000/> GET /
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: close
Transfer-Encoding: chunked

welcome

ルーティングを追加する。

service.js

/**
 * service.js: Define the web service
 */
var journey = require('journey');

exports.createRouter = function() {
  var router = new (journey.Router);

  router.map(function() {
    // GET '/'
    this.root.bind(function(req, res) {
      res.send('welcome.');
    });

    // GET '/hello'
    this.get('/hello').bind(function(req, res) {
      res.send('hello!');
    });

    // POST '/user'
    this.post('/user').bind(function(req, res, params) {
      console.log(params.user);
      res.send(200);
    });

    // GET/POST '/echo'
    this.path('/echo', function() {
      this.get().bind(function(req, res, params) {
        res.send(params);
      });

      this.post().bind(function(req, res, params) {
        console.log(params)
        res.send(200);
      });
    });
  });

  return router;
};


ルートは個別に定義することもできるし、グループ化することもできる。

this.get('/foo').bind(function() { ... });  // GET '/foo'
this.path('/bar', function() {
  this.get().bind(function(req, res) { ... }); // GET '/bar'
  this.get('/baz').bind(function(req, res) { ... }); // GET '/bar/baz'
});


server.js

var http = require('http'),
    service = require('./service');

var router = service.createRouter();

http.createServer(function(req, res) {
  var body = '';

  req.on('data', function(chunk) {
    body += chunk;
  });

  req.on('end', function() {
    router.handle(req, body, function(route) {
      res.writeHead(route.status, route.headers);
      res.end(route.body);
    });
  });
}).listen(3000);

console.log('Server running at http://127.0.0.1:3000');


http-consoleで確認

% http-console http://localhost:3000
> http-console 0.6.0
> Welcome, enter .help if you're lost.
> Connecting to localhost on port 3000.

http://localhost:3000/> GET /
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sat, 09 Apr 2011 04:29:06 GMT
Server: journey/0.4.0
Content-Length: 22
Connection: close

{ journey: 'welcome.' }
http://localhost:3000/> GET /hello
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sat, 09 Apr 2011 04:29:08 GMT
Server: journey/0.4.0
Content-Length: 20
Connection: close

{ journey: 'hello!' }
http://localhost:3000/> GET /user
HTTP/1.1 405 Method Not Allowed
Allow: POST
Date: Sat, 09 Apr 2011 04:29:13 GMT
Server: journey/0.4.0
Content-Length: 31
Connection: close

{ error: 'method not allowed.' }
http://localhost:3000/> POST /user
... { name: 'daigo3' }
HTTP/1.1 200 OK
Date: Sat, 09 Apr 2011 04:29:22 GMT
Server: journey/0.4.0
Connection: close
Transfer-Encoding: chunked

http://localhost:3000/> GET /echo
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sat, 09 Apr 2011 04:29:28 GMT
Server: journey/0.4.0
Content-Length: 2
Connection: close

{}
http://localhost:3000/> GET /echo?q=hi
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sat, 09 Apr 2011 04:29:39 GMT
Server: journey/0.4.0
Content-Length: 10
Connection: close

{ q: 'hi' }
http://localhost:3000/> POST /echo
... { q: 'hello' }
HTTP/1.1 200 OK
Date: Sat, 09 Apr 2011 04:29:54 GMT
Server: journey/0.4.0
Connection: close
Transfer-Encoding: chunked

レスポンスで"Server: journey/0.4.0"となっているのはルートのコールバックが返すres.send()でbodyのみを指定しているため。res.send(status, header, body)の様に引数を渡すと、レスポンスを定義できる。

パラメータの処理

this.get().bind(function(req, res, params) {
  console.log(params);
});

の様にパラメータを取得する方法と、URLをキャプチャする方法がある。

this.get(/^([a-z]+)\/([0-9a-z]+)$/).bind(function(req, res, resource, id, params) {
  res.send({
    resource: resource,
    id: id,
    params: params
  });
});
http://localhost:3000/> GET /books/32?p=1234
HTTP/1.1 200 OK
Content-Type: application/json
Date: Sat, 09 Apr 2011 05:00:05 GMT
Server: journey/0.4.0
Content-Length: 50
Connection: close

{
    resource: 'books',
    id: 32,
    params: { p: '1234' }
}