Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

how to respond if request bypassed ? #44

Closed
nick7ikin opened this Issue · 6 comments

2 participants

@nick7ikin

Bypassed action is called each time crossroads can't match any route. Crossroads passes requestString parameter to the action and I can't do anything except logging. Is there any ability to send 404 or close connection? I think it would be great to have response and request objects available in the "bypassed" action.

@millermedeiros

There are a couple of different ways to do it, but they all involve adding the listener for the bypassed signal from inside the request event handler (since request and response will be different at each time), I would probably do it like this:

var http = require('http'),
    url = require('url'),
    crossroads = require('crossroads');

http.createServer(function (req, res) {
  crossroads.normalizeFn = function(str, vals){
    // handlers will receive request as 1st param, response as 2nd
    // and an object with all captured parameters as 3rd argument.
    return [req, res, vals];
  };

  var bypassedBinding = crossroads.bypassed.add(bypassedHandler);
  // set the first 2 arguments passed to the handler
  bypassedBinding.params = [req, res];

  crossroads.parse( url.parse(req.url).pathname );

  // we remove the listener since it isn't needed anymore
  // (we can only have a single bypassed dispatch per request)
  // this is important otherwise it would keep adding a new listener
  // for each request.
  bypassedBinding.detach();

}).listen(1337, "127.0.0.1");


function bypassedHandler(req, res, requestString) {
   // do your 404 magic here!
   // request object and response are available!!
}

I added a link to this issue on the examples page at the wiki at the part I show how to normalize the dispatched values.

This is the kind of scenario where it's good to have a tool that is flexible enough so you can change the default behavior at will, that's why I use Signals in 99% of my projects.

Crossroads wasn't really created thinking about node.js specifically (I use it mostly for client side), it just happen to be flexible enough that you can use it on other environments as well. I thought about creating a "node adapter" which would pass this kind of info by default but as you can see it's just a few lines of code so I'd rather let the user be free to do whatever he want and use the same source files for all environments.

Do you think it would be better to add node.js specific method/wrapper (maybe a crossroads.requestHandler only available inside node.js) or just improving the docs would be enough?

Cheers!

@nick7ikin

Thanks for your explanations.
I think crossroads should act in similar way when request is bypassed or not. Currently when the request is routed the normalizeFn functions is called. It gives ability to pass "request" and "response" needed in route handlers.
But if the url is bypassed the nomalizeFn is not called. And that's why I can't get req/resp objects in default handler.
So I think Crossroads should call normalizeFn in all cases. That will prevent additional code.

@millermedeiros

I will keep this issue open, I'm considering to add an option on the parse method to set the default arguments, right now it only accepts a string as first param.. planning to add an array as second so we can remove the normalizeFn altogether, I think it will make more sense and reduce the amount of boilerplate. This is a pattern common enough so we should support it.

Thanks for asking it, I'm not using Node.js that much (besides to write some build/helpers scripts) so I wouldn't realize it anytime soon. Planning to add this to the dev branch next week.

Cheers.

@millermedeiros

check the dev branch, just added an option to make it easier (pass an array with default arguments to crossroads.parse), planning to release v0.8.0 soon, maybe just implement #43 first (since it's easy) and than later I release v0.9.0 wit the other features. thanks once again for reporting it.

@millermedeiros

Here is an example on how to do it after my last commit (v0.8.0-alpha):

var http = require('http'),
    url = require('url'),
    crossroads = require('crossroads');

http.createServer(function (req, res) {
  crossroads.parse(url.parse(req.url).pathname, [req, res]);
}).listen(1337, "127.0.0.1");

way cleaner... will be definitely included on the next release. req and res will be the first arguments passed to the route.matched, crossroads.bypassed and crossroads.routed.

@millermedeiros

this feature was just merged into master and pushed to npm! npm update crossroads

@millermedeiros millermedeiros referenced this issue from a commit
@millermedeiros Merge branch 'dev'
* dev:
  add rest segment support. closes #43. bumps version to 0.8.0.
  add defaultArgs to crossroads.parse to make it easier to use on node.js. closes #44
  revert normalization behavior to using constants instead of methods. closes #31
  change build to nodejs
  add methods to toggle normalize behavior. closes #31
  add switched signal. see #37.
0cf0d9c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.