Refactor routing to a pattern-based implementation #110
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This pull request refactors the
web.Routing
class to use regular expressions for routing. This reduces complexity (by removing more than 200 lines of code) and increases performance (by not delegating to a variety of method calls) while sacrificing a completely flexible way of routing requests by using matcher functions, while adding the possibility to route patterns.Route patterns
...are essentially regular expressions, with the small difference that
.
matches its literal form and that the^
and$
metacharacters cannot be used due to how the patterns are constructed. If you want to match a single character use\C
instead. Here are a couple of examples:/(favicon.ico|robots.txt)
matches the files favicon.ico and robots.txt (but not favicon_ico, which a regular expression would match)/(?i)test.html
using the internal-optional syntax matches the file test.html in any case/users/[a-z]+
matches /users/test but not /users/0815.HEAD /
andHEAD
both match HEAD requests to the root path.Route patterns are matched against
/[PATH]
or[METHOD] /[PATH]
if they do not start with forward slash.Compacting
With route patterns, the following typical routing definition can be rewritten in a more compact way:
BC breaks
Routing::routes()
to return[:web.Handler]
instead ofweb.Route[]
CannotRoute
now lives directly in theweb
package instead ofweb.routing
.Routing::with()
Routing::mapping()
See also
https://pkg.go.dev/net/http#ServeMux