Previously, the middleware stack passed the router a C, but this was
both odd semantically (a pattern which mutated the environment might see
a *different* environment) and bad for perf: it cost us an allocation.
Now we only pass around *C's internally.
Importantly ("importantly"), this gets us down to 0 allocations for the
static routing case, and one allocation (the URLParams map) for the
normal routing case.
Let's just hope the GC does its job correctly and don't try to help it
out. This case is probably triggered very infrequently since most people
set up their middleware before they accept a single request, and it's
worth about 100ns of perf on the common case for us if we get rid of the
defer.
The "name" parameter was originally a workaround for the fact that function
pointers in Go never compare equal to each other (unless they are both nil).
Unfortunately, this presents a pretty terrible interface to the end programmer,
since they'll probably end up stuttering something like:
mux.Use("MyMiddleware", MyMiddleware)
Luckily, I found a workaround for doing function pointer equality (it doesn't
even require "unsafe"!), so we can get rid of the name parameter for good.
They say that every programmer builds a web framework at some point. This one is
mine.
The basic idea behind this one is that I wanted a Sinatra for Go, and I couldn't
find one anywhere. Furthermore, net/http is in many ways really close to what I
want out of a Sinatra-in-Go, and many of the frameworks I did find seemed to
reinvent too much, or were incompatible with net/http in weird ways, or used too
much questionable reflection magic. So long story short, I wrote my own.
This implementation is only half-baked, and among other things it's missing a
whole lot of tests.