

Thoughts on Martini – Introducing Negroni - sld
http://codegangsta.io/blog/2014/05/19/my-thoughts-on-martini/

======
nemothekid
I have been using Martini for over a year and we use it on our frontend API
which has a non trivial number of endpoints, that contain a lot of code that
has little to do with http routing (like I imagine most products do).

Yes, Martini is non-idiomatic magic. Specifically codegangsta's 200-line
inject
([https://github.com/codegangsta/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](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.

~~~
elithrar
> Gorilla (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)`.

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!

------
cnbuff410
For me, stdlib + some mux library is still the way to go until someday I see
the shortcomings.

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.

------
VeejayRampay
Props to @codegangsta for showing a lot of people that ego doesn't belong in
rational discussion about weaknesses and strengths of a
framework/language/piece of software.

Fantastic attitude. Take the criticism, try to separate yourself from your
instant reptilian gut feeling and improve on all that.

------
TheMagicHorsey
Never liked Martini, but hats off to the library author on taking criticism so
well and changing directions. High quality person he is, to take things this
way, and not be defensive. I'm looking forward to his future work.

~~~
crashandburn4
I was going to say, seems very classy, but what do you expect from someone
that calls their framework martini. :)

------
codegangsta
Thanks for the positive feedback guys!

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!

------
8ig8
Just in case... How to make a Negroni with Anthony Bourdain.

[http://youtube.com/watch?v=MNxWjRU8oxU](http://youtube.com/watch?v=MNxWjRU8oxU)

------
dscrd
I've used Martini a bit and also tried some of the other frameworks (beego and
revel) and I really don't see what makes people call Martini especially non-
Gooey in comparison.

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".

~~~
enneff
Except that's obviously not the case, considering he just announced Negroni,
an idiomatic ("non-magical") library that provides the key feature of Martini.

~~~
dscrd
...which has even less features than Martini.

~~~
enneff
Because it doesn't need them. There are more polished versions of those
features elsewhere, and they can be composed easily with Negroni as they all
use the same interfaces.

I thought your point was about the necessity of magic in a web framework. The
most magical thing about Martini was its dependency injection approach, which
Negroni provides in an idiomatic way.

Unless you're saying that it's the magic that makes a framework a framework,
as opposed to just a collection of libraries. That makes sense, because the
magical approach of Martini (for example) does, in a sense, lock you in to
using Martini. This makes it more like the monolithic web frameworks you
mention.

------
marcosvm
I love this post, I was at Gophercon and met several gophers. This post shows
how the Go community is made and how we're going forward. Thank you
@codegangasta.

~~~
schleppy_oc
I second this. The people I met at GopherCon were among the top group for any
community built around a language.

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.

------
rebelidealist
Why not change up the Martini core instead of creating yet another lib for
people to learn, write code for, and maintain?

~~~
Djehngo
Because the things he changed were fundamental to Martini core. Changing it
would require a re write of any code which touched Martini's API. Because
people use that project it's better to start a new one with a different
philosophy.

~~~
rebelidealist
_sigh_ we keep re-inventing the wheel instead of optimizing a solution that
people are relying on.

~~~
MetaCosm
You misunderstand. There is no optimizing, he built a non-idiomatic library
that people love. It has pros and cons -- he is going to maintain it. There is
no "fixing" it -- what makes people love it is it being NON-IDIOMATIC.

ADDITIONALLY -- he has built something that is idiomatic and looks to solve
the same problem set as the original tool. This is a "have your cake and eat
it too" situation.

------
ryanseys
Not mentioned in the blog post but he also tagged Martini at v1.0 today [1],
making its API locked in, if anyone is so inclined to keep using it.

[1]: [https://github.com/go-martini/martini/releases](https://github.com/go-
martini/martini/releases)

------
sanatgersappa
Awesome response to criticism. Also, love the direction this takes.

------
mholt
Martini's "Hello world" is averaging about 60-90 microseconds on my machine.
Negroni clocks in at 30-50.

I think both libraries have their advantages.

------
yewsi
Sounds great. In a broader context, I don't know why people pick on Go (aside
from it being an 'evil Google creation') -- especially when many of Go's
critics are _also_ people who claim to support simplicity and consistency in
programming languages. I have a good feeling Go will become dominant in the
no-so-distant future, so rather than knock it, why not help grow it / make it
better?

------
ctdavies
I just love Campari.

