node-restify: Routes and middleware not run in defined order
Bug Report
Restify Version
v7.2.1
Node.js Version
v10.5.0
Expected behaviour
In restify v4, using the serveStatic plugin before including any middleware would not run the middleware when serving a file.
Actual behaviour
Middleware is now run prior to serving files.
Repro case
const restify = require('restify');
const errors = require('restify-errors');
const server = restify.createServer();
server.get('/', restify.plugins.serveStatic({
directory : './public/',
default : 'index.html'
}));
server.use((request, response, next) => {
return next(new errors.ForbiddenError('Nope'));
});
server.get('/api/test', (request, response, next) => {
response.send({});
return next();
});
server.listen(8000);
Expected: Request to /
serves index.html, request to /api/test
gives a ForbiddenError
Actual: Request to both /
and /api/test
gives a ForbiddenError
Cause
Changes somewhere between v4 and v7, presumably the change in routing/middleware handling.
Are you willing and able to fix this?
No, there appears to be other issues with serveStatic in general so this should be tackled as part of sorting the overall problem out.
About this issue
- Original URL
- State: open
- Created 6 years ago
- Comments: 17 (8 by maintainers)
@alechirsch, I had the same issue, and I ended up using
restify-router
, which allowed me to:This changed removed one of the core features that our application needs. We have the same use case as most on this thread.
Can a flag on server creation be implemented to preserve the ordering that handlers are registered? We can not upgrade to the latest version as it will break our API.
While the documentation for use() is correct in 7.x, this breaking behavior really needs to be added to the migration guide.
Hi all - this was a deliberate change, one unfortunately poorly documented. We definitely could have done a better job on this front 😦 The intention was to get away from unintentional bugs as a result of shifting
use/pre/{verb}
statements around in the code, and moving towards explicit ordering specified by the API. For example:Would result in:
Moving the statements around would not change the output. Since
pre
,use
, and{verb}
all take arrays, existing behavior is possible by leveraging factories of some sort to “bind” common middlewares for use cases like auth, e.g.:We’ve also seen teams build out a JSON config mapping for their URLs to handlers, and use that to programmatically install routes and bind auth only when the route specifies it.
Ultimately, the behavior is more consistent, although at the cost of verbosity. We’ll definitely need to update the docs to reflect this change more explicitly. We understand this might not be to everyone’s liking; we should definitely continue the conversation if there are use cases we can better support.