steambap / koa-tree-router

high performance router for Koa

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support auto-generated OPTIONS handler / Distinguish between 501 and 405 errors

lehni opened this issue · comments

First of all, thank you for creating this router! After looking at koa-router's code, I realized that performance should be much better if it was backed by a tree structure and went looking further, and found this!

One feature that koa-router offers that appears to be missing here, but would probably be really easy to implement is the allowedMethods() middleware.

From a quick glance at the following lines it looks like the functionality is mostly there, it would just need to be exposed through a handler:

const allowList = [];
// Search for allowed methods
for (let key in router.trees) {
if (key === ctx.method) {
continue;
}
const tree = router.trees[key];
if (tree.search(ctx.path).handle !== null) {
allowList.push(key);
}
}
ctx.status = 405;
ctx.set("Allow", allowList.join(", "));

Also, it looks like currently when a method is not found, the router always sends a 405 error back (but only if a onMethodNotAllowed() handler is defined, why not always send a default one?), without distinguishing 405 and 501, as koa-router does:

https://github.com/alexmingoia/koa-router/blob/590df78ef38a557e9ce86a14bd9bfe567c5701a1/lib/router.js#L419-L450

Some more information:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501

ZijianHe/koa-router#7

Would you accept a PR for this? Do you have any opinions on how it should be controlled through options?

First of all, I would definitely accept a PR for distinguish between 501 and 405 errors.

There are 2 reasons that I do not set a default handler:

  1. I only want to have 405 in my dev environment, not in production. In that way, I can get some hint on what is available in dev environment while not expose those informations in production.
  2. I usually have a "catch all" handler somewhere in my actual app. In such case, passing a callback to router level seems less flexible.

@steambap unfortunately I've now decided to use a different approach for routing that is not based on koa-tree-router, so I won't find the time to implement this. The main problem was that it wasn't tolerating such routes to coexist:

'/users/current'
'/users/:id'

etc.

I know there are Golang tree-based router that support those routes. However, if I'm using a tree-based, I want the best performance. That's why my implementation is based on httprouter, which does not support such routes.