restify optional route parameters

silverfighter picture silverfighter · Dec 18, 2013 · Viewed 12.4k times · Source

Hi I have an routing issue with restify.io

It seems like restify does not support the "?" for optional parameters as express.js does.

server.get('/users',function(req,res,next){});
server.get('/users/:id',function(req,res,next{});

// I even tried server.get('/users/',function(req,res,next){});

So everything works as expected when I run

1

http://localhost/users

which shows all my users

2

http://localhost/users/1 

which shows the user with id 1

http://localhost/users/ //(note trailing slash)

fails with resource not found because this one is interpreted as empty parameter instead of route #1

I don't want the check for empty parameters on each and redirect or pass on to next ...

This seems like a common thing which should hit others too... so what is your take on that to not get an 404 for trainling slashes in the url

Answer

srquinn picture srquinn · Dec 18, 2013

You need to add restify.pre.sanitizePath() somewhere near the beginning of your code:

var restify = require('restify');

var server = restify.createServer();
server.pre(restify.pre.sanitizePath()); // Add this line

For more details, look at this Github Issue. The original paper on ReST indicates the slash has a special meaning, however, ReST is NOT a standard, only a guide. Thus, the use/omission of a slash is a matter of the API designer's preference and the semantics of the API. Consistency is the ONLY thing that matters.

I mocked and tested your setup and this is confirmed to fix your problem as described:

var restify = require('restify');

var server = restify.createServer();
server.pre(restify.pre.sanitizePath());

var users = [
  { id: 1, name: 'Sean' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Ana' }
]

server.get('/users', function (req, res, next) {
  console.log(req.query());
  res.send(users);
});

server.get('/users/:id', function (req, res, next) {
  var user = users.filter(function (user) {
    return user.id === req.params.id;
  });
  res.send(user);
});

server.listen(8080, function() {
  console.log('%s listening at %s', server.name, server.url);
});

HTTP tests:

$ curl localhost:8080/users <- Returns all users
$ curl localhost:8080/users/ <- Returns all users
$ curl localhost:8080/users/1 <- Returns user with id 1
$ curl localhost:8080/users?name=sean <- Logs querystring
$ curl localhost:8080/users/?name=sean <- Logs querystring