Yes, Martini is non-idiomatic magic. Specifically codegangsta's 200-line inject (https://github.com/codegangsta/inject) library is most of Martini's magic. I think inject is rather clever (I've begin using it other projects), while non-idiomatic, and is a pretty neat way of handling middlewares - which I think is the most important point.
In defense of Martini however I do appreciate that it leaves out boilerplate in many of my functions, and while my functions may look magical (who is calling this?), the routing setup and parameters provide a certain clarity. Concerning Stephen Searles post, I feel #2 & #3 are problems with the library specifically and not Martini's design. In #2, the default return handler doesn't check if the return value satisfies io.Writer, which it should, but the default return handler can be fixed or swapped by the developer to make sure io.Writer is handled appropriately. #3 can be seen as any issue when your router allows you to specify Regex routes, and with that you have to ensure your routes are valid Regex. If you don't like it, you can specify to not take advantage of it or do whatever the popular Gorrilamux does.
Now #1, is a tough one and overlooks what a lot of the other mini-frameworks have been trying to provide and what Stephen's muxchain doesn't provide - how do I manage all the various resources like database connections, config parameters, and the like. How can I write one "User" middleware, and provide the clients login details cleanly to my other middlewares and handlers? muxchain simply makes that the developers problem, so while it claims to provide everything Martini does, I don't really think it does. Gorrila (through Gorilla Context), stretchr's Goweb, Goji and others provide a `map[string]inteface{}.` Okay, so I still lose the type system, but now I have to litter my code with a ton of `realValue, ok := myMap["myValue"].(myType)`.
The only simple, type-safe solution I've seen to this problem is Gocraft's web (https://github.com/gocraft/web), which I discovered long after Martini, and is much faster. So far of the frameworks that have been developed because of the whining that Martini has too much magic, only Gocraft has a rather clever way of dealing with this problem.
Finally however, I'd imagine in most production applications the router is such a small part of the project I can't really suggest to someone that they should use Python+Twisted for their application if they like Martini. I can understand to a beginner or someone looking to learn Go, Martini may be poisonous, but in real, working, code I've rarely had to even think about Martini, and the rest of my code is fairly idiomatic and type safe.
In short, while I do think Negroni is a great project, I think the whole reflection/injection might be a little too blown out of proportion. We will have a better picture for Martini at the end of the day once the Go ecosystem matures but its a little bit premature to say we should stop writing new code with Martini.
This is a good point, and it's something that—after you write a few pieces of middleware in any web application—you run into pretty often.
I avoid repeating things by creating quick Set and Get methods around that type that save me having to write out a type assertion; ok { } block every time, but there's still some repetition when it comes to dealing with the error.
Martini, for all it's "warts", is a fairly well thought out project and it's popularity is not an accident—even if it isn't idiomatic Go.
FWIW, I've started to look into Goji and like it a lot. There is /some/ interface{} there, but any type issues are at least caught on program initialisation (so you don't get bitten later), you get a request context without a global map/lock, and middleware is anything that satisfies http.Handler. I'm happy to give up a tiny bit of compile time safety* for a saner API and the extra things I've mentioned above. You generally have to be trying to give it the wrong type anyway, from my experience.
gocraft/web (as you have touched on) takes an interesting approach by having you create your own Context, which can then wrap any types you might pass around in your request context. The function chaining in the README is a little ugly, but you otherwise get a) type safety and b) no type assertions when dealing with context. The downsides seem to be a need to rewrite (to some extent) any middleware that already satisfies http.Handler to incorporate the web.NextMiddlewareFunc type instead, unless I'm misinterpreting that.
* Perhaps I'll regret saying this!
But this is a very classy and admirable way to answer all the critics. He didn't take them offensively at all. Instead he puts more thoughts on the design objectively and sincerely, and come up with what might be a better architecture in the end.
Hats off to codegangsta and good luck on Negroni.
Fantastic attitude. Take the criticism, try to separate yourself from your instant reptilian gut feeling and improve on all that.
The Go community overall has made me a better developer, and I'm so excited to see where the community takes the language in the next couple years!
The reality is, when your language is as weak as Go (in terms of advanced features), a framework with any sort of significant features will be quite dynamic and "magic".
I spoke at length with someone there about Martini, and had pretty much the same take on it as Jeremy now professes. The stuff he did with the dependency injection was really solid, but as he admits, it is not very idiomatic. I applaud his new effort while maintaining the existing project that so many are using.
I think both libraries have their advantages.