Documentation

coffeemate edited this page Mar 10, 2011 · 15 revisions
Clone this wiki locally

About Install Quickstart Documentation Guide Source

Documentation

Meryl request

Meryl extended http request object passed as a parameter to meryl.h and meryl.p callback functions which gives you some utilities to handle http request data coming from the client.

req.params

Object containing query string and path parameters with url info

meryl.h('GET /list/{item}', function(req, resp) {
  // try: GET /list/comments?pagesize=10
  resp.end('Listing ' + req.params.pagesize + ' '
    + req.params.item);
});

req.postdata

Buffer object received from the clients. It's a raw data which must be processed to refine if required

meryl.h('POST /preview', function(req, resp) {
  // echo post data as text
  resp.setHeader('content-type', 'text/plain');
  resp.end(req.postdata);
});

Meryl response

Meryl extended http response object passed as a parameter to meryl.h and meryl.p callback functions which gives you some utilities to shape http response data delivering to the client.

resp.render(templateName, data)

Renders a template name by manipulating it with given context data.

meryl.h('GET /', function(req, resp) {
  resp.render('homepage', {foo: 'bar'});
});

resp.redirect(location)

Helper method that redirects client request to another location.

meryl.h('GET /', function(req, resp) {
  resp.redirect('/another_page');
});

Meryl

The Meryl object itself.

meryl.options

Options object which is used to configure meryl

There are three pre-defined options. These are:

  • templateDir: Used to point the path of directory containing the templates. Default is an empty string.
  • templateExt: Template file extension. The default is '.jshtml'
  • templateFunc: Template rendering engine interface. This option takes a function which take two parameters. First one is the string content of the template while the second one is template context object. See 'examples' directory for sample applications.

meryl.handle(expr, callback)

Registers a new http handler to global Meryl instance. First argument is the routing pattern which combines http verb with path expression while the second one is the callback function which will be executed in meryl context. If router pattern matches any http request the given callback executed with current req, resp objects.

If more than one handlers registered with same router pattern only the first registered one will be executed.

Routing pattern is very simple in mind:

$HTTP_VERB $PATH_EXPRESSION

The whole expression builds a meryl flavored reqular expression which exposes two types of path parameters.

  • { ... } – curly braced parameters are partial, they match until the meet '?', '/' or '.' character
  • < ... > – tagged(!) parameters are greedy, they match whatever they meet until you denote a block character.

Here are some examples:

  • {method}
  • GET /
  • POST /index.html
  • PUT /long/path/index.html
  • DELETE /delete/something?foo=bar
  • GET /posts/{postid}
  • GET /posts/this-is-a-long-post-id
  • GET /posts/32432
  • GET /files/.{ext}
  • GET /files/filename.pdf
  • GET /files/this/is/a/long/file/path.pdf
  • GET /(index.html)?
  • GET /
  • GET /index.html

Let's take look at a concrete example like below:

meryl.h('GET /repo/<filepath>/{version}', function(req, resp) {
  var fileContents = readRepo(req.params.filepath, req.params.version);
  resp.end(fileContents);
});

Also there are shorthand helper functions mapped to individual http methods. You can declare handlers implicitly by using meryl.get(expr, callback), meryl.post(expr, callback), meryl.put(expr, callback), meryl.put(expr, callback) functions. You must omit explicit http method names in expressions

meryl.get('/posts/{postid}', function(req, resp) {
  resp.end('reading post: ' + req.params.postid);
});

meryl.put('/', function(req, resp) {
  throw 'not supported';
});

meryl.plug([expr,] callback [, callback])

This function registers a plugin to the global meryl instance. More than one plugin can be executed on the same matched http request within the registration order. Plugin system simply exposes a middleware implementation for Meryl.

First argument is a router pattern which is also mentioned in meryl.h before.

The second one is the callback function which takes usual req, resp objects and alsa a function reference argument named 'next'. If you finished your work inside the plugin, you simply call 'next' to jump over to the next registered plugin.

You may want to break plugin iteration, then do not call 'next' method but be sure to end the http response in some way. Otherwise all the request/response pipe will hang which makes no sense for client side.

Here is a sample application demonstrating plugins.

// app.js

var meryl = require('meryl');

function validate(u, p) { return false; }

meryl.p('*', function(req, resp, next) {
  resp.setHeader('server', 'meryl-nodejs');
  next();
});

meryl.p('{method} /private/*', function(req, resp, next) {
  if(validate(req.params.uname, req.params.passwd)) {
    next();
  } else {
    resp.statusCode = 401;
    throw 'access denied';
  }
});

meryl.p('GET *', function(req, resp, next) {
  console.log('logging all GET requests');
  next();
});

meryl.h('GET /(index.html)?', function (req, resp) {
  resp.end('Demonstrating plugins');
});

require('http').createServer(meryl.cgi()).listen(3000);

If you pass only callback function as first parameter by omitting expression Meryl assumes expression as '*' to match all requests.

meryl.p(function(req, resp, next) {
    resp.setHeader('server', meryl-nodejs');
    next();
});

Also you should mind appending more callbacks. It is very useful when registering pre-defined modules.

var connect = require('connect');
meryl.p(connect.static('/srv/static_content'), connect.logger());
meryl.run();

meryl.fabby([opts] | ([expr] [,callback [, callback]]))

This is a funny function which features fabjs like chaining of Meryl plugins and handlers.

var connect = require('connect');
var meryl = require('meryl');

meryl.fabby
  (connect.logger(), connect.static('/srv/static_content'))
  ('GET /', function (req, resp) {
      resp.render('home');
    }
  )
  ('GET /posts/{postid}', function (req, resp) {
      resp.render('post');
    }
  ) 
  ('GET /posts/{postid}/comments/{commentid}', function (req, resp) {
      resp.render('comment');
    }
  )  
  ();

meryl.handleNotFound(cb)

Custom 404 file not found handler

meryl.handleError(cb)

Custom 500 server error handler

meryl.factory()

returns a new Meryl instance

meryl.cgi(opts)

It's the main entry point for Meryl. It returns a function reference for using with nodejs's built-in http module while creating a server instance. You can pass an object for further using in Meryl context such 'this.options'.

require('http').createServer(meryl.cgi({debug:true})).listen(3000);

meryl.run(opts)

Helper function that runs Meryl instantly by wrapping it with an internally created http server. It returns running http server instance.

meryl.run({debug:true, port: 8080}))