Restify
Created: 2016-03-16 09:01:10 -0700 Modified: 2018-08-01 15:04:31 -0700
This is a REST server and/or REST client that is lighter weight than using Express.
body vs. query vs. params
Section titled body vs. query vs. paramsIf you have a function like this:
someFunction(req, res, next) {}
“req.query” will be set if you did a “GET” command and have question-mark parameters right in the URL like “/users?id=1&name=Adam”
“req.params” will be set if you specified the route like this: ‘/users/:userId/:name’
“req.body” will be set if the client sent them in the body of the request as opposed to the headers or URL.
I throttle using the plugin that they provide. It has two interesting options: “ip” and “xff”. If “ip” is specified, the IP address of the connection will be used for throttling, which is undesirable when you’re behind a load balancer since all requests will have the IP address of the load balancer and will thus get rate-limited very quickly. To get around that, you can use “xff”, which will take the “x-forwarded-for” header (code reference). This won’t exist on localhost though (actually, it won’t exist in production either unless you’re definitely behind a load balancer), so you’ll get undefined, which Restify treats as “always allow and never throttle” (code reference).
I ran into a problem on 3/16/2016 where I was throwing an exception from inside a route, e.g.:
// this.server.listen() code goes here
this.server.get(‘/ping’, (req, res, next) => {throw new Error(‘hello world’)});
When I would GET the “/ping” route, the REST client would get this response:
{
“code”: “InternalError”,
“message”: “hello world”
}
This was incredibly difficult for me to track down because I expected the REST server to display the error somewhere before passing it off directly to the client (possibly leaking implementation details in the process).
I figured out what was going wrong. Restify has an ‘uncaughtException’ handler by default which outputs a 500 error to the client with the error message (e.g. “hello world”). This is what it looks like (taken from their source on 3/15/16):
server.on(‘uncaughtException’, function (req, res, route, e) {
if (this.listeners(‘uncaughtException’).length > 1 ||
res.headersSent) {
return (false);
}
res.send(new InternalError(e, e.message || ‘unexpected error’));
return (true);
});
As you can see above, if you install your own handler, it will essentially turn off their handler because they do a handler-length check. Here is a much saner handler:
this.server.on(‘uncaughtException’, function (req, res, route, err) {
console.error(‘Restify uncaughtException: ’ + err);
res.send(new InternalError(e, e.message || ‘unexpected error’));
return (true);
});
This is roughly the same as the default handler, but instead of blindly sending errors out, it also logs to the server. You would use a handler like this when you trust the client (e.g. for internal services).