6 ms·
On Go’s Web Application Ecosystem
- codegangsta 13y agoAuthor of Martini here. I think right now is a very exciting time for web development in Go. One of the goals of Martini is to rally developers to create some more reusable web modules in the form of handlers and middleware. Martini has gotten a great response because it doesn't infringe it's api on your modules/middlewares. I personally think that this is the way to move forward with web development in Go. Less coupling, pull in the dependencies you need, get stuff done.
- codebeaker 13y agoFrom someone who's betting the farm on writing a web application in Go (https://www.harrow.io/ https://www.harrow.io/). We've chosen Go for two really significant reasons: a) to reduce attack surface area and b) to enable us to distribute binaries to customers who want an enterprise/firewall install inside their own network. Speaking about surface area, we've reduced the amount of framework code in stack (rails, gems, etc are all off the table) to zero, and we've reduced the app paths to a few tens of lines of code, in most cases. Whenever one trades off a framework "to make things more secure" one has to be sceptical, there's a massive scope to introduce SQL injection, XSS and other nasties. In Go, in our case this is fairly limited. So take that reason with a pinch of salt if you aren't building a VERY well defined app with VERY small and skilled team. I don't expect this to scale well. The second part is also a niche value, whilst it will have some benefits for us running our hosted version of Harrow, it'll have more profound benefits when we can sell binary installations to customers. Finally, learning how to build applications in an API centric manner, without the crutch that is Rails has been interesting, and has made us all better programmers, we have a more interesting architecture now, and are making better use of our tools (we're leaning heavily on PostgreSQL, triggers, stored procs, LISTEN/NOTIFY etc) and we have a faster system. On the flip side of things, timing attacks are now really something we have to be mindful of. For instance the login endpoint returns "404 Not Found" regardless of whether it's an incorrect password, or the account doesn't exist. Except, interestingly we're using bcrypt (we're switching to pdbfk2 before the public launch) we need to look up the user before we can hash and verify the password. Meaning we respond in < 1ms when the user is not found and 4ms when the user is found, but the password is incorrect. (and 4ms when the password is valid). This also applies to a lesser extent in responding with "404 Not Found" when trying to snoop on someone else's project/logs/build/etc. The same way they Github does. But it's less critical there as there isn't the artificially long password hash comparison step. All told the decision to build in Go has made the development of the project slower, but has in my mind at least lead to a better quality of software, with things that don't typically show up in Rails/et al projects (foreign key constraints, triggers in the DB). Of course all these tools are sharp weapons if handled incorrectly, and testing triggers/functions in the database can be a nightmare from a unit/functional testing point of view. We've avoided technology proliferation (the entire stack is Go, and PostgreSQL, with worker nodes which rely on LXC). The entire application uses three packages not taken from the Go standard library. (db driver and bcrypt library) Ohh, and our test suite compiles, and runs (all of it.) in less than three seconds. That hasn't hurt much, either.
- danaw 13y agoJust an FYI, noticed two typos on your homepage: "easyily" => "Easily", and "ause" => "use". Interesting approach to the stack, I'm considering the same for some side projects. I like the exercise in a fully API driven approach. A major advantage is the pure separation of client and server means refactoring/changing languages becomes more straightforward you can also isolate data/logic from presentation more cleanly.
- codebeaker 13y agoGreat catch, thanks - we're not pushing the homepage too hard yet :) so my pride isn't too badly hurt. Rolling a replacement soon!
- valevk 13y agoI think Go is still missing its killer-web-app-framework. But maybe it's better that way. Keeps out the people who don't like think before they code.
- jerf 13y agoMost people seem to define killer-web-app-framework to include a "blessed" ORM solution. (I don't personally, but I understand where people are coming from.) Go seems to have been resistant to any large-scale ORMs to date; it's hard to put why into a quick HN post, but the language seems to sort of resist it, despite having some reflection capabilities. Or at least, the language resists the sort of ORMs that the web world has become accustomed to, with tons of convention-over-configuration and such. A more static one could probably be done. I find myself wishing the "go" toolchain would give me a defined way of running certain code before the compiler, so I could generate Go code with the go source tools. From there you could easily compile yourself up some ORM code by examining a database at runtime. It's yet another privilege it claims for itself but gives you no way to hook into.
- tootie 13y agoI've become a real fan of Flask and the core framework does very little beyond managing request routing and having a simple framework for using jinja templates. Everything else should be optional. My day job is Spring MVC which is an absolute behemoth. It's an application framework more than just a web framework and the plethora of gadgets are useful for alleviating a lot of architecture decisions, but I'm sure I could get by without them.
- throwmeaway2525 13y agoThis article seems to be pushing Martini, which at first glance looks interesting (though it doesn't appear to have been mentioned on the mailing list even once, so there may be some boosting involved). There is Revel, but it seems to be getting a bad rap ("non-idiomatic" label used as a stick).
- codegangsta 13y ago
- deleted 13y ago[deleted]
- INTPenis 13y agoWhat about web.go? I never tried it but it seemed promising.
- elithrar 13y agoAs touched on in another HN thread: web.go isn't "actively" maintained by the author. Whilst any of the packages mentioned in the article could succumb to the same fate, I made an effort to highlight some of the longer running projects. Gorilla is probably the cornerstone here.
- buro9 13y agoOne thing I'd like to see in Go is a way to sanitise HTML based on a whitelist. This is to accompany blackfriday (Markdown) and text/template (templating). Markdown permits HTML, and this allows some scope for nasty stuff to get in, or for bugs that may exist in blackfriday to be exploited leading to HTML that could be the source of a XSS attack. We're currently running our user generated content through this: https://github.com/microcosm-cc/cleanse https://github.com/microcosm-cc/cleanse and more specifically this: https://github.com/microcosm-cc/cleanse/blob/master/src/main/java/Cleanse.java https://github.com/microcosm-cc/cleanse/blob/master/src/main... Which is a set of rules for OWASPs HTML sanitizer: https://code.google.com/p/owasp-java-html-sanitizer/ https://code.google.com/p/owasp-java-html-sanitizer/ This works extremely well, except for the fact that it means in our Go code we're calling out to a process and asking for a Java process to be kicked up for each request. If no-one beats us to it we'll be porting that to Go... but for us it remains a "When we need to" from a scaling or performance perspective. Still... we'd love to see group work on a whitelist based sanitiser that we can contribute to rather than us go and write our own at some indeterminate point in the future.
- jws 13y agoIn moving a site from PHP to go in a rewrite, I'm about to head down that same road. The plan is to use the HTML parser from the "not quite in the real distribution but kind of official" net repository: http://godoc.org/code.google.com/p/go.net/html http://godoc.org/code.google.com/p/go.net/html Parse the HTML, walk the result, write that which is acceptable. I have to restrict by tag, url scheme, and url server name in various contexts.
- buro9 13y agoI looked at that myself, and decided that it wasn't the path I should go down. ParseFragment throws an error on bad input, but actually I just want that stripped and to carry on processing things. If a user has put in a mostly usable piece of HTML and then got something wrong as an error rather than bad intent then permissiveness in how we handle that should rule. And then I wondered about the wisdom of creating a potentially large security library on a not quite nailed down API. Ultimately, given that this is a security thing, I figured it's best to go with the proven many-eyeballed solution that was had widespread acceptance. Feel free to use the package we've provided, the bit of go code you need for it is: import ( "os/exec" ) func SanitiseHTML(html string) (string, error) { cleanse := exec.Command("java", "-jar", "/usr/sbin/cleanse.jar", "--permissive") writer, err := cleanse.StdinPipe() if err != nil { return "", err } _, err = writer.Write([]byte(html)) if err != nil { return "", err } err = writer.Close() if err != nil { return "", err } buff, err := cleanse.Output() if err != nil { return "", err } cleanse.Start() return string(buff), nil }
- ungerik 13y agoNot in the post: the go-start framework https://github.com/ungerik/go-start https://github.com/ungerik/go-start
- retzkek 13y agoAlso worth mentioning is Hugo, a static site generator: http://spf13.com/project/hugo http://spf13.com/project/hugo
- shadowmint 13y agoAnyone have a link to an open source web app of a non-trivial nature built in go? I've seen lots of system utility stuff, but I don't think I've ever actually seen anything other than how-to-use-this-framework web apps?
- breakpete 13y agoThere is https://github.com/peterskeide/bones https://github.com/peterskeide/bones (I'm the author). It's by no means a large codebase, and it's not finished, but the goal is to give you a decent starting point with some hopefully useful idioms to build on.
- taude 13y agoI'm curious as to why everyone wants a web-framework in Go. Wasn't it primarily designed for back end service-type-of-stuff? Seems like there's plenty of full-stack and micro-web frameworks out there in what ever language you desire, that are in a more web-dev friendly syntax. I guess I don't picture a company saying, we're going to use GO through-and-through for our dev platform. I picture it more as a "well, we now have a custom messaging service that needs to scale better" or something, much like when people choose to drop into C or C++. It also seems that there's more dev-friendly languages to build the web layer in.... I also don't see many web-dev types thinking in GO very well. So, why GO at the web-layer?
- pstuart 13y agoBecause it's fast, a pleasure to code in, and simple to distribute.
- taude 13y agoThe distribution story is definitely appealing. I think it was only the other day a post showed up here with someone making command-line tools with it. I find this appealing.
- jws 13y agoFor me: • I prefer to find my errors at compile time. Consider the time to find and fix a missing method in a go compile (one 'make' and all the info is still in the developer's brain cache) versus eventually having a user drive the website into that method and having a mystery occur on a duck typed language. (hope you have good stack trace logging on the back end) • I prefer a language that doesn't repeatedly break all my code. When I write and deploy a site, it should stay written. (Looking at you PHP. Granted, this was over a period of 15+ years, but all the more reason I don't want to go back and look at that code.) • Efficiency is nice if you are ever going to hit a performance bottleneck. To elaborate: you get to defer the "OMG I need to map this load over more than one machine!" crisis for a while, and if you end up in a "I need N machines!", then making N smaller is good for your well being. • Builds are fast enough that I don't care. I generally have a makefile for a website anyway to get everything organized and encoded, one more rule to build the go is no burden. The weakest spot I'm finding is the html/template end. My strong typing evaporates at that boundary. I'd rather have the template get precompiled into go code and then compiled into functions with nicely defined interfaces on its parameters; faster to run and catch all those typos in field names. The current go mindset of a "go only", non-extendable, build command forecloses experimentation in this direction. (Unless you are a barbarian from the olden days, like me, and wrap everything in a Makefile.)
- pearkes 13y agoWhat I find interesting about Go[1] and the web application community is that people constantly point to speed as a huge selling point. Speed in the sense of latency and request volume per server. I still feel like for the majority of cases, this type of speed difference is not going to matter. The difference between the Go built in web framework at 190,687[2] (1.3 ms) json responses per second and Flask, a popular Python framework at 18,945[2] (3.1 ms) is trivial when you look at the bigger picture. If you are receiving enough traffic for that to make a fundamental difference, you'll likely have enough potential or realized revenue to pay for a few more [Flask, Rails, "slow" framework] servers, or have enough developer time to warrant building it in Go. The upside to using a "slow" framework is massive. Try writing an app like Ticketee[3] in Go, even with Gorilla et al and you'll realize the productivity gains you're missing out on. For a small API, backend services, command line apps Go makes sense. But the big selling point there isn't speed, it's likely deployability. I love Go. It's good for teams, deploys well, is enjoyable to program in, does things quickly. But if a client comes to me wanting a web application with forms, view logic, payments, 3rd party integrations – I'll take my Rails, thanks. > Given all this, frameworks (and ecosystems) like Flask, Sinatra, Django and Rails still have an advantage for when you want to get something done today: they’re very useful toolboxes, handle a lot of the boilerplate and have a lot of examples and packages to leverage. The author clearly recognizes this opinion – but there seems to be an idea that you can just "use Go" in place of existing web frameworks. That's not the case (yet!). I think this is largely driven by the myth of performance requirement. [1]: Things like Node.js probably fit into this argument too [2]: http://www.techempower.com/benchmarks/ http://www.techempower.com/benchmarks/ [3]: https://github.com/steveklabnik/ticketee https://github.com/steveklabnik/ticketee
- taude 13y agoNice arguments for "deployability" not something I initially would have thought to measure, since it's usually something that's "felt" later in the development/release process. I guess it'll be interesting to watch how the frameworks mature and start to approach the Rails/Django or other micro-frameworks...
- jaegerpicker 13y agoI'd disagree that node.js fit that argument. I do python Django in my day job and a ton of node.js in my other projects (startup nearing launch, two other projects) and with express there is not a huge gulf in productivity between the two. All of my node.js projects is based upon No-SQL (leveldb, mongodb, couchdb) db's so I'm not up on JS's ORM libs but it might be a large difference there but it's certainly not when using a No-SQL db.
- voidlogic 13y agoAll this talk about HTML templating (html/template, etc) & Go web applications, is missing any discussion of what IMHO is a better way to write Go web apps: 1. Write a backend webservice in Go's net/http + Gorilla 2. Use something like angular JS to interact with those webservices. (From the server's perspective this means static HTML/CSS/JS assets that can again be served by Go, from memory if desired). 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.
- danaw 13y agoThat's the approach I'll be taking when writing a future side project. Fully API driven with go. Angular/Grunt/Bower for frontend, perhaps served by go or possibly on a separate machine serving just HTML, just to see how it performs. I've even considered Github pages for the HTML. But probably not for production :)
- Aissen 13y agoI've came to like some of the components of ghost: https://github.com/PuerkitoBio/ghost https://github.com/PuerkitoBio/ghost
- playing_colours 13y agoWhen I read all these posts praising Go, I feel like a stranger accidently appeared at someone's birthday party. I really want to start loving Go, it looks perspective and people already benefit from using it, but I just cannot make me enjoy the language. Having Java/Scala background I used to have static checking and performance for free and I cannot feel about Go the same as someone who switched from Python, PHP, Ruby stacks. I code mainly in Scala, and even if I like Go's simplicity, compilation speed and the absense of Java burden, I really miss features like default immutability, pattern matching, generics, reach collection toolset, powerful typesystem. The language looks just not expressive for me to really enjoy. Maybe I am corrupted with FP, cannot value simplicity or I should focus more on getting things done not on the process of writing code. Just wonder, if anyone else have similar impressions / feelings?