

Martini: Classy web development in Go - abhia
http://martini.codegangsta.io

======
simonw
I really like the look of this. There's some very clever API design going on
here, and it's clearly taking advantage of Go's language features rather than
just trying to be a clone of a framework from another language.

I particularly like the service injection concept. Django forces every view
function to take a request object and return a response object. Flask makes
these optional, but then requires you to use global variables to access more
information from the request. Martini attempts to resolve any arguments it
sees by looking up their static type against a service directory. I think
that's really clever.

The way it allows you to stack up Handlers is neat too. Django does this with
either globally applied middleware or per-view-function decorators, but
there's something really neat about just taking a list of functions for things
like authentication and "stacking" them on top of each other - or having that
same function applied as middleware to every request using m.Use(func...).
Using Context.Next() to allow that middleware to "wrap" a request (the
equivalent of Django's process_request and process_response pair) is clever as
well.

Colour me impressed!

~~~
elithrar
> The way it allows you to stack up Handlers is neat too.

Ditto. I _especially_ like that it's fully compatible with the existing
http.HandlerFunc interface, which is a big deal. This means you can just write
"regular" handlers as middleware (or bring them over from existing code)
without having to reinvent the wheel.

I also very much like the way it leaves sessions up to you. A few other Go
frameworks leverage http.Cookie, instead of letting you use something like
gorilla/sessions. I'm a big proponent of server-side sessions (wherever
possible) given how simple gorilla/sessions + Redis can be to set up.

I'm a little tempted to use this myself (I've been going mostly naked so far)
for my weekend (read: also weeknight) project, given that all the "real" logic
(middleware, DB queries, etc.) can be dropped in alongside it.

~~~
codegangsta
Yup. Making the "dropping in" part easy is partly why Martini can be kept
clean on the number of dependencies it pulls in. The only external dependency
on Martini is
[https://github.com/codegangsta/inject](https://github.com/codegangsta/inject)
which I maintain anyway :)

------
steilpass
A list of Go webframeworks. Sorted by activity. Last commit as of 14. Nov 2013

[https://github.com/codegangsta/martini](https://github.com/codegangsta/martini)
Last commit: 2 hours HN discussion:
[https://news.ycombinator.com/item?id=6731022](https://news.ycombinator.com/item?id=6731022)

[https://github.com/astaxie/beego](https://github.com/astaxie/beego) Last
commit: 1 day ago

[https://github.com/robfig/revel](https://github.com/robfig/revel) Last
commit: 4 days ago
[https://news.ycombinator.com/item?id=5996712](https://news.ycombinator.com/item?id=5996712)

[https://github.com/aaronlifton/Gooo](https://github.com/aaronlifton/Gooo)
Last commit: 1 month ago
[https://news.ycombinator.com/item?id=5057108](https://news.ycombinator.com/item?id=5057108)

[https://github.com/hoisie/web](https://github.com/hoisie/web) Last commit: 5
months ago
[https://news.ycombinator.com/item?id=6715547](https://news.ycombinator.com/item?id=6715547)

[https://github.com/paulbellamy/mango](https://github.com/paulbellamy/mango)
Last commit: 9 months ago

~~~
gravityblast
here another one :)

[https://github.com/pilu/traffic/](https://github.com/pilu/traffic/)

------
codegangsta
Author here. Super flattered to see all the feedback coming in. I built this
package to suit my own picky needs.

Martini is meant to be non-intrusive and braindead simple to use. Hope you
guys like it!

~~~
euphemize
looks great, thanks!

------
peferron
I usually don't like video walk-throughs, but this one was very snappy and a
pleasure to watch.

By a happy coincidence, I was just going to start building an API backend in
Go today or tomorrow for a side project, and was thinking about doing it with
vanilla Go but now I'll probably give Martini a shot (!).

~~~
jol
This one was good, I don't know if there is sound as I watched it silently,
but it was perfect even without it.

Im hooked, likely to start learning go soon. P.s. Big respect for being able
to make the video below 3 min.

------
slashclee
Would be really nice if the demo was in a normal web page instead of a video.
(Also, I'd love to know what vim(?) extension provides the interactive
completion with the function signatures! That looks really cool.)

~~~
terhechte
Probably gocode, which is a daemon that works with different editors to offer
autocompletion (i.e. vim, emacs, etc):
[https://github.com/nsf/gocode](https://github.com/nsf/gocode)

~~~
beefsack
GoSublime also utilises gocode for ST users:
[https://github.com/DisposaBoy/GoSublime](https://github.com/DisposaBoy/GoSublime)

------
jjsz
This appeared in reddit[1] before Hacker News and he has already been asked[2]
how does this compare to revel and beego.

[1]
[http://www.reddit.com/r/golang/comments/1qlfvp/martini_class...](http://www.reddit.com/r/golang/comments/1qlfvp/martini_classy_web_development_in_go/)

[2]
[http://www.reddit.com/r/golang/comments/1qlfvp/martini_class...](http://www.reddit.com/r/golang/comments/1qlfvp/martini_classy_web_development_in_go/cde0yez)

------
lukeholder
Great work Jeremy. Although there are a number of web frameworks similar to
Sinatra on go, this feels to me to be the most natural. The care taken to
present this well shows this project has promise.

Are you looking to make this more full featured with an ORM/persistence layer
(i.e Rails) or keep it small and similar to Sinatra?

~~~
codegangsta
The idea is to keep it small with lots of packages that work with it. It is
easy enough to add any ORM instances (gorp, gorm) as a service so it can be
injected into a Martini Handler.

Thanks for the feedback!

------
semisight
Very cool. Reminiscent of express.js, but statically typed and in Go. I may
look at this for future projects.

~~~
mmgutz
Looks like a lot of reflection. At that point, I would just stick with express
and node. All that magic comes at a cost.

~~~
elithrar
> Looks like a lot of reflection. At that point, I would just stick with
> express and node. All that magic comes at a cost.

There's _one_ use of reflection[1], and it's to ensure that the argument is a
function.

Reflection isn't inherently bad; using it at the drop of a hat is.

[1]:
[https://github.com/codegangsta/martini/blob/master/martini.g...](https://github.com/codegangsta/martini/blob/master/martini.go#L102)

[edit]: Looks like I missed the `inject` import (thanks breakpete)

~~~
breakpete
There is more. The dependency injection implementation is based on reflection,
using the
[https://github.com/codegangsta/inject](https://github.com/codegangsta/inject)
package.

See e.g

[https://github.com/codegangsta/martini/blob/master/martini.g...](https://github.com/codegangsta/martini/blob/master/martini.go#L136)

[https://github.com/codegangsta/martini/blob/master/martini.g...](https://github.com/codegangsta/martini/blob/master/martini.go#L75)

Still, the end result is a nice API.

------
VeejayRampay
Newbie question here, I've looked into gorilla/mux before, how does Martini
compare to it? Do they serve the same purpose? Does it offer more features? Is
it easier to use?

Great-looking website by the way. The first impression is a good impression,
it's very polished.

~~~
beefsack
Martini seems to be a bit more of an inclusive solution more akin to something
like Revel, whereas Gorilla seems to be tackling the problem by making a
number of standalone components that you can tie together yourself.

I've done a small project in both Revel and with Gorilla components and found
that I actually enjoyed implementing things using Gorilla packages more,
giving a great deal of flexibility and not hiding too much in the framework
like Revel does.

------
ithkuil
Very nice. It can be easily used to serve subtrees of another go web framework
that accepts http.Handler (e.g. appengine):

    
    
        m := martini.Classic()
        // ...
        http.Handle("/", m)

------
beefsack
This is amazing, I love the DI with services! I always preferred Gorilla to
things like Revel because it wasn't so opinionated, and this seems closer to
Gorilla but with this clever idea of services.

I threw together an example app with templating and database access as
services, I'm impressed by how concise it is.

[https://gist.github.com/mickhrmweb/7479583](https://gist.github.com/mickhrmweb/7479583)

------
forsaken
Seems to be missing documentation.

~~~
simonw
The docs in the README are a good start:
[https://github.com/codegangsta/martini](https://github.com/codegangsta/martini)

In fact, having now read the rest of the code, they're pretty much
comprehensive.

