Gadget: A smallish web framework for Go(redneckbeard.github.io) |
Gadget: A smallish web framework for Go(redneckbeard.github.io) |
Edit: Just discovered [Martini](https://github.com/codegangsta/martini), that's exactly what I wanted.
That's where I say NO. go's reflect package is slow and a nightmare to use. Go's JSON parser, which uses reflect, is 2.5x slower than Node.js (in my own benchmarks [1]). And Go 1.1 was 3.5x worse that Node.js at parsing JSON. Again, those are my benchmarks, but they seem consistent with what other people are finding (from my Googling around).
I would not make this trade off, I would not use reflect on EVERY request, just so that my request handlers are compatible with http.HandleFunc. It almost seems silly to do that. That's why other frameworks (like Revel) are using custom Request objects.
However, I do understand why the author is emphasizing this feature. If your handlers are incompatible with http.HandleFunc (i.e. if they take a custom Request object), you need your own Router which invokes the handlers, and you need your own ServeMux, so you end up giving up on a lot of functionality from net/http. That's why Revel has a ton of custom objects that mirror what net/http has and it proxies method calls.
So you keep wondering: "why the hell am I writing so much seemingly unrelated code? I just want to add a 'user' property to each request, but now I've coded so many struct's and created so many files". It makes you feel unproductive and it bloats the code.
Again, I've made my choice, but you should be aware of such caveats and, of course, benchmark things yourself.
1) My benchmark results. For some charts, higher is better, for others, lower is better. Use your judgement. http://goo.gl/xfWFXo
How's the performance? I'm a little afraid of the "reflection" boogeyman, but I don't have any experience to say what kind of impact we're talking about here.
I'm coming from Rails day-to-day, and a very light, compiled Go web backend is a refreshing change of pace. I'm leery of giving up the simplicity of net/http, but if it stays small maybe it's the way to go. Right now I'm popping in gorilla toolkit, though, so if martini is as "light touch" as that, I'd be up for using it.
BTW, great work, that's exactly what I was looking for.
1) I didn't want routes in a text file. This is whiny, I know. Just a personal preference. 2) Go is the only programming language that has held my attention long enough to actually finish a fairly usable framework. Writing a framework is a good exercise in software design, so I felt like I had to use the opportunity.
I ask because I am looking to put my weight behind a framework and am undecided, but not at all attracted to Revel...
[1] http://gruntjs.com/ [2] https://github.com/gruntjs/grunt-contrib-watch
https://github.com/codegangsta/dotfiles/blob/master/vim/vim/...
I've even made it rewrite (eradicate) templates that don't compile (threats).
https://github.com/aybabtme/brog/blob/master/brogger/templat...
At this point, the code is kind of messy, so please overlook that. I also have a bare deployment on an t1.micro : http://www.antoine.im/
Just trying to express the same redneckbeard said: until it is a very thin bottleneck, this should be no problem.
Lots of people have abandoned Rails for Sinatra, or Django for Flask. That's totally cool, and there are good reasons to do so. There are also very good and obvious reasons to use something that further abstractions common patterns if the software you are building conforms reasonably well to those patterns.
But in 2013 do I really want to use server side HTML tempalating? Why not just connect a webservice to a HTML/JS presentation layer like I am suggesting? If all you are doing is building a webservice then the abstractions beyond net/http + Gorilla are not buying you much IMHO, but they do come at quite a performance cost: http://www.techempower.com/benchmarks/#section=data-r7&hw=i7...
My first couple Go web applications did things the html/template way and were structured on the way I used to go JSF applications- but since I switched to the above approach my projects have been better performing, faster to develop , better scaling and easier to maintain. As we all know, we seldom get all those things in one technology choice without trade-offs.
I personally have seen a great improvement in code simplicity, readability, and overall DRYness when projects are written using Martini.
Choosing a framework isn't about following some sort of socially acceptable way to build your web apps. Just build them! If a framework solves a problem for you then use it, otherwise keep using net/http handlers.
I've started writing subpackages as they become important to me. The most useful thus far is probably gadget/forms, which is very much inspired by Django forms. I prefer a data validation layer that is independent from or at least very loosely coupled to a model layer.
Here's the squashed versions of...
- Camping (currently 4.031 kb over 55 lines) - https://github.com/camping/camping/blob/master/lib/camping.r...
- Squatting (currently 3.929 kb over 68 lines) - https://github.com/beppu/squatting/blob/master/lib/squatting...
https://github.com/codegangsta/martini
You and I sir, are on the same wavelength
You should consider adding benchmarks to that it is easy to compare martini to net/http. This will let you keep an eye on performance as you work on it and accept pulls.
http://www.techempower.com/benchmarks/#section=data-r7&hw=i7...
In that benchmark Go's JSON performance is almost 3x higher than that of Node.
Any reasons why there's such a big difference?
I measured the speed with which Go and Node.js decode/encode JSON, i.e. there is no network and web server involved, just json.Marshal()/json.Unmarshal() vs JSON.parse()/JSON.stringify()
I benchmarked the web server speed separately.
Many people do yes. It may seem old-fashioned but when I load a web page I don't want to sit looking at a 'loading' message or a progress bar before I even see the content as json is turned into html, and I'd rather all the logic was server side and a flat page was served to a web client (browser).
I don't agree doing rendering server-side necessarily means a significant performance cost, or is harder to maintain or slower to develop, why do you think that is the case? Caching and a server-side framework can make things far faster and easier, depending on what you are doing, and raw speed of rendering is not often an issue nowadays anyway.
I'm not sure what the test you pointed to there was showing, because using Go to output json could be done with a framework too by just bypassing the framework, in exactly the same way. It hardly seems a relevant test, and there were other issues in those tests when I looked at them previously - like comparing wildcard routes in one test to hard coded ones in another. Comparing bare JSON production with go to JSON production with webgo (do people use webgo?) is hardly very useful or a fair comparison. It would be trivial to make those equal in speed and I suspect the diff will just be down to different routing and/or template rendering. In addition, I don't want clients to see JSON, so the rendering speed of that is pretty irrelevant, what matters to most people is when html finishes rendering.
It would be interesting to hear the reasons behind the string of assertions in your penultimate sentence, are you sure all types of app would benefit equally from your approach? Can you describe the advantages as you see them to this approach?
This is how bad implementations look to users, consider something like Gmail as a counter example however...
>would be interesting to hear the reasons behind the string of assertions in your penultimate sentence
Sure:)
>are you sure all types of app would benefit equally from your approach?
Of course I am not, I didn't make a that claim. I think most typical applications benefit, it has worked well for me. I was asking questions to understand the point of view I don't hold-
> Can you describe the advantages as you see them to this approach?
In this approach:
Performance:
1. Most assets are (server side) static
2. They are pre-gzipped and stored in memory using a little reusable code I wrote.
3. They are extremely cache friendly
Better scaling:
1. Only a fraction of the previous work happens server side... You using your users compute power.
2. You are transfering less data.
Faster to develop/easier to maintain:
1. This way you have two differnt apps that happen to talk to eachother. This makes it easy to replace one or the other.
2. Responsibilities are clearly defined. This makes brining new people up to speed easier and makes thingse asier to test, debug, etc.Of course I am not, I didn't make a that claim.
Sorry, I should have phrased that differently as something like - perhaps not all types of app would benefit equally? I wasn't trying to put words in your mouth. I do think it's a little early to start asking why anyone would use server-side logic any more, there is room for both approaches :)
Perhaps if you are serving data which is text-only, static and fits well into json as you describe, and don't mind coding in Javascript, client-side is a better fit. If you have a lot of server-side data and editing/auth requirements (more of a CMS), and depend on heavily nested templates etc, server-side may be a better fit, though I'm sure it's possible to handle every type of website in theory using either system. There is also the question of which language you prefer to work in - personally I'd rather keep JS use to a minimum, as it's pretty gnarly.
Re the separation of concerns, yes this is a valid point and is something you gain from serving an API if you have a complex system, though it is possible to have a back-end behind a traditional web framework too, with one side being the API serving json or whatever and a separate user-facing service serving HTML.
I don't think speed or caching are a big problem with server-side frameworks nowadays though, and I'd rather use a language like Go than JS to produce web apps. Out of curiosity, which client-side frameworks are you using?
Gmail isn't a counterexample to the "loading" message thing. It manages to be slow on hardware and network connections that are incredibly fast.
On the other hand, the complexity you're punting on needs to go somewhere, so now you'll need to muck about with something like Angular to make up for it. Difficult choices. It kind of continuously feels like we're on the edge of Nirvana with this stuff and something perfect in its elegance will emerge. I'm only 24 but this seems like a dangerous siren song to me... maybe we should all know better by this point, eh?
>though it is possible to have a back-end behind a traditional web framework too.
Sure I think you get a lot of the maintainability pro's this way, but loose on some of the performance ones.
I mostly write systems software (in Go), but when I write webapps I use angular.js (frontend) + Go (backend) + One of many datastores (ex MySQL, Postgre, LevelDB etc)