I ain't switching from Perl 5.8 to golang until a shared hosting provider becomes available.
Goji: a web microframework for Go
71–80 of 88 posts
Re: Goji: a web microframework for Go
#72> I have very little interest in boosting Goji's router's benchmark scores. There is an obvious solution here--radix trees--and maybe if I get bored I'll implement one for Goji, but I think the API guarantees and conceptual simplicity Goji provides are more important (all routes are attempted, one after another, until a matching route is found). Even if I choose to optimize Goji's router, Goji's routing semantics will not change.
Maybe you can just use HttpRouter without reimplementing it yourself?
https://github.com/julienschmidt/httprouter
> The router is optimized for best performance and a small memory footprint. It scales well even with very long pathes and a large number of routes. A compressing dynamic trie (radix tree) structure is used for efficient matching.
goji.Get("/hello/:name", hello)
router := httprouter.New()
router.GET("/hello/:name", Hello)Re: Goji: a web microframework for Go
#73Re: Goji: a web microframework for Go
#74Do we yet have the Django for Go? Goji is as said a microframework, what I want is an equivalent of Django.
Microframeworks written in Go are more likely to replace Django Rest Framework [1] than Django itself
Re: Goji: a web microframework for Go
#75Earlier quoted context omitted.
Actually, Goji grew out of a single deficiency in "pat": the fact that it does not have a standard way of defining request context. The big use case here is how you'd write a middleware that did authentication (using API keys, session cookies, ???) and emitted a username for other middleware to consume. With net/http, you end up with a lot of coupling: your end handler needs to know about every layer of middleware ab…
I agree that 'context' and passing this context between middleware is the biggest missing item from the standard http+"pat". This library (Goji) solves it with a map[string]interface{}. This works, but has the downside that you need to type-assert your values from this map if you want to use them. I wrote a library a while ago ( http://www.github.com/gocraft/web ) that uses reflection so that your contexts can be str…
On one hand, a library can allow its users access to typed structs—this is the way gocraft/web does it. The upside here is huge: applications are now type-safe, and can lean on the compiler to enforce their own correctness. The library code that backs this behavior can be arbitrarily gnarly, but you only have to write it once, after which it'll Probably Be Correct (tm).
On the other hand, you can provide a standard "universal" context type like Goji does. Since the library makes no statements about the sorts of fields you have or their types, applications have to do a bunch of shenanigans with type casts in order to extract the typed values they expect. The upside here, however, is the standardization and what that allows. I've found that in most of the web applications I've built, only a small fraction of the middleware is authored by me: I end up pulling in the standard request logging middleware, or the middleware that assigns request IDs, or the middleware that does CSRF protection. There's a huge amount of value in being able to write (read: "let someone else write") those middlewares once and being able to use them in any application. With arbitrary application-provided structs, this isn't possible [1], but if you can instead standardize on types and keys out-of-band, you can mix and match arbitrary middleware with impunity.
This alone is one of those awkward engineering tradeoffs where you're exchanging one nice thing (application-level type safety) for another (standard interface, and hopefully an ecosystem of drop-in middleware), and given just this I'd argue that the ecosystem is probably more important. But the frosting on this particular cake is that, with only marginally more awkwardness, you can actually get application-level type safety too: look at what I did for the request ID middleware that ships with Goji, for instance (https://github.com/zenazn/goji/blob/master/web/middleware/re...). Again, it's not quite as nice as a user-defined struct, but in the grand scheme of tradeoffs and sacrifices, I don't think it's so terribly bad.
So TL;DR, Goji chose standardization and composability in the design of its context object over application type safety, but if you're willing to write a few helper functions I don't think you end up losing the type safety anyways.
[1]: actually, come to think of it, with a lot of reflection and some struct tags you could probably pull it off. (Something like "struct { RequestID string `context:"reqid"`}", and the request ID assigning middleware would hunt around for a string field tagged "reqid"). But it seems like it'd introduce a lot of coupling between middleware and the application which I'm not sure will turn out well—any time a middleware needed a bit of extra storage, every application would have to change. In any event, if someone builds this I'd love to play around with it.
Re: Goji: a web microframework for Go
#76I see why some would call Martini "magic" but I'm not entirely sure I prefer having to deal with a giant `map[string]inteface{}`. What you are really doing is moving the "magic" from the framework and onto the developer (I now have to do type checking and casting). That said I'm a huge fan of Martini and I actually use codegangsta's Inject in my other projects to manage shared state/resources, so I am heavily partial…
Re: Goji: a web microframework for Go
#77About this part in README: > I have very little interest in boosting Goji's router's benchmark scores. There is an obvious solution here--radix trees--and maybe if I get bored I'll implement one for Goji, but I think the API guarantees and conceptual simplicity Goji provides are more important (all routes are attempted, one after another, until a matching route is found). Even if I choose to optimize Goji's router, G…
Without having looked in detail at httprouter, I think the most obvious reason it might not be sufficient is that it doesn't support regular expressions. This might not be a dealbreaker, but I'm fond of the occasional regex route, and I'd have to think long and hard about whether it's worth giving up for a faster router. And plus, I'm still not sure router speed actually matters for most applications.
In any event, I do have a long plane trip coming up, and I'm sure Goji will grow itself something at least slightly more efficient than a linear scan then. I'm think Goji's router and middleware stack are already zero-allocation, so it'll just be finding a way to binary search through routes.
Re: Goji: a web microframework for Go
#78When I read things like "func Get(pattern interface{}, handler interface{})" I start questioning why this whole thing is ever written in Go at all? This kind of ditches half of Go's benefits by moving all type checks to run time.
I decided that the sin of exposing an interface{} as a parameter was less egregious than the sin of multiplying Goji's API surface area by a factor of 8, but you'll be happy to know that passing a value of the wrong type causes the invocation of Get (Post, etc.) to fatally exit immediately. If you're defining all your routes in a single goroutine before calling goji.Serve() (which is probably the most common way to define routes), your application will crash before it even binds to the socket.
So, not quite as good as a guarantee enforced at compile time, but it'll have to do.
Re: Goji: a web microframework for Go
#79When I read things like "func Get(pattern interface{}, handler interface{})" I start questioning why this whole thing is ever written in Go at all? This kind of ditches half of Go's benefits by moving all type checks to run time.
If Go supported method overloading, you could actually write the types of those functions out. The first one is either a string or a regexp.Regexp, and the second one is one of four variations on an http.Handler, giving a total of 8 varieties of each function. I decided that the sin of exposing an interface{} as a parameter was less egregious than the sin of multiplying Goji's API surface area by a factor of 8, but y…
Re: Goji: a web microframework for Go
#80Earlier quoted context omitted.
"even if you're using something like Angular and a "single-page" type architecture; you pay a huge price in flexibility for it" Can you elaborate more on that statement? I use angular/golang api and rails/angular both often.
I find the HTML templating options for Golang particularly painful, is the subtext there. (I like Golang a lot; we did the bulk of microcorruption.com in it. But the web front end, which is a tiny amount of code, that's a Rails app.)
It's a bit of a hack/convoluted solution but it allows you to make use of a few javascript template libraries which are IMHO more pleasant to work with.