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.
> 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.
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 which I maintain anyway :)
Thanks for the feedback! I knew from the beginning that I didn't want to create another clone framework. The Golang community needs something that is in line with it's own philosophies.
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 (!).
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.)
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?
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.
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.
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.
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.
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!