1. Holy crap, this is like coding in early Java days, what the heck were the language designers smoking?! They just ignored everything! Where's my testing framework! DI?! Build system, dependency management?! WTF.
2. Holy crap, this is like coding in the early Java days! This is awesome! I can understand all golang code I read! Everything is so simple and easy. I finally get "less is more", and "worse is better"!
3. (Many months later) Oh god, I'm getting so sick of writing this test assertion in 4 lines over and over, and writing 100s of lines of mock structs. My tests are 5% substance and 95% setup. Okay let's write a junit/mockito assertion library. Oh crap, I'm having to manually wire everything everywhere and it's such a pain. Let's write a DI library. Ugh my project is getting too big and `go get` just doesn't cut it - time to use a dependency management library. Ugh, makefiles only go so far, time to write a build tool. Ugh code generation and metacoding is nonexistent, let's write our own code generation tool so we don't have to hand build 100s of types. ETC.
4. (Distant future) As golang's stubborn designers finally accept some flaws in their original thinking, they add features to make the language look a lot like another widely used language at the Googplex. Mission accomplished?
P.S. This is somewhat tongue in cheek - I do enjoy using golang day to day. It is a refreshing change :).
I'm sure this comment was written in good faith, but it doesn't belong at the top of this thread. It could be attached to virtually any post about Go. It barely engages with the actual post at all. Practically every other top-level comment below it is better.
And, of course, it spawned a completely useless thread litigating Java vs. Go. Perhaps that's why it's at the top of the thread --- which means voting had a perverse effect for this topic.
I don't know what to do about this tendency in language threads on HN, but it's a real problem.
Appreciate it was written as tongue in cheek, but I am glad that today a developer can start with Go, test, write code, build, deploy all with Go, whereas nearly every other ecosystem requires additional tools, often external competing tools. Then life becomes about having to learn whole new toolbekt before even coding.
Go still keeps it lean, and is great.
The fact it does not have hipster dev approved status is also an added bonus. The minute we see a bloated testing suite with yet another DSL, for Go, we are in trouble.
You forgot 5. (In a more distant future) After a plethora of features, long time Go developers become disappointed with how much bloat the language acquired over the years, decide to start from scratch and design the definitive language to replace it. Go to 1.
Well, hundreds of lines of mock structs is probably a sign that there is something very fundamentally wrong with the code. Go, as a language, has nothing to do with it. Testing is one of its nicest features. I only had to improve my testing experience just a bit, like stringifying complex outputs to compare them easily, comparing all of outputs with expected outputs in a single if statement and issuing a single verbose t.Errorf on failure, showing what functions produced what outputs on what inputs and what was expected.
It will get extremely meta when golang's infrastructure gets good enough for other languages to want to use. Then they'll split it out into a 'GoVM', or I guess 'GoRT', and then you'll have a 'GoVM' competing with the JVM...
The article sort of glosses over IntelliJ with the golang plugin as an "other" IDE, but it's best in class hands down. At one point in my past I had sworn off of Java-based IDEs, and used Sublime Text for years with primarily Python and Go. Something convinced me to try Go in IntelliJ, and really it's fantastic.
It also covers "important-to-me" features the author mentions. I haven't tried VSCode yet, but have tried all the others listed. IntelliJ is fantastic for Go.
> Only func main has the right to decide the flags that will be available to the user.
This one applies to every language. I was working with a python package that decided that, since `sys.argv` was available from anywhere, it should parse `sys.argv` to configure its own behavior. For a long time, their suggestion was to first parse `sys.argv` yourself, then to modify it before going into the library.
Reminds me of when systemd parsed the kernel command line for the kernel debug parameter, making life hell for kernel devs.
It was so ridiculous, someone ended up sending in a patch for the kernel to modify the command line once it had been parsed to remove the debug parameter.
I agree but find it bizarre that this tip comes in a list of best practices for the major language invented at Google, when the same company's "gflags" library, also heavily used, advertises right at the top that it allows definition of flags in any source file!
https://gflags.github.io/gflags/
This defeats the purpose of a good flags library though.
Where flags shine is when you've some obscure tunable deep in the dependency tree that you need to tweak (particularly in an emergency). Plumbing through potentially thousands of flags through to main is nonsensical in that scenario.
After working with .NET/Java/Node.js/Ruby/Python etc the move to Go involved a larger investment in time. I found this really informative and it's great to have the learnings condensed down.
Check out YouTube conf. talks from the same author, where he shared his experience developing services in Go, while working at SoundCloud. Also, very helpful.
I have run a coding-dojo type project internally at work at ADP. We had two PRs in Go, so while we are on this topic, are there any improvements that can be made to the Go submissions?
Does anyone want to submit a best-practice Go solution?
Good article on the whole, but I have a few quibbles:
> If your repo foo is primarily a binary, put your library code in a lib/ subdir, and call it package foo.
IMHO, that's just ugly, uglier than foo/foo or foo/foolib or foo/libfoo.
I also think that anything which has commands other than a single-command project which will always be a single-command project (there are fewer of these than one might think …) should put all commands, even a single one, in cmd/.
I think that inline config objects should be used with useful zero values to try to emulate Lisp's or Python's keyword arguments: if one always needs to provide a value for each config object member, then just use arguments after all.
I think a testing library can be a great addition, since it can turn a three-line if check into a one-line assertion.
> IMHO, that's just ugly, uglier than foo/foo or foo/foolib or foo/libfoo.
> I also think that anything which has commands other than a single-command project which will always be a single-command project (there are fewer of these than one might think …) should put all commands, even a single one, in cmd/.
It's this kind of inflexibility in the directory structure of ones repo that really turned me off of Go. It's such a trivial thing, and yet the fact that Go lacks a level of indirection (package.json, Cargo.toml, pom.xml, etc) to map a chosen directory structure to the standard build tooling causes problems that get really annoying. For instance, there's a ton of Go repositories out there that are not go gettable because the author wanted to put source code under a src directory and hacked that together using make. And good luck with organizing any repository that contains multiple languages where go is one of them...go's "code lives at the repository root" doesn't play well with others.
It all makes me sad since Go's decentralized dependency management (i.e. go get being able to pull/build based on a meta tag) is brilliant and I always hate having to rely on a single, centralized repository to deal with dependencies.
> I think a testing library can be a great addition, since it can turn a three-line if check into a one-line assertion.
Totally concur with this. I feel like all these people complaining about "bloated test frameworks" either haven't written a lot of tests, or are just fine with repeating themselves in test code, or they end up writing their own version of a test framework anew in every project. So much simpler and sane to grab an off the shelf solution for test code.
It was a great talk at QCon London earlier this year - the video is due to be published towards the end of next month. I'll try and come back to this thread when it is with the URL.
(Disclaimer: I was the track host for Perer's talk)
"those parameters should be part of type constructors"
I'm not sure if this is a nit, a misunderstanding on my part, or a difference in terminology, but I think what is meant here is "value constructors" (or more commonly, just "constructors"). As I understand the term, "type constructors" construct types.
Libraries using log.Printf are incredibly tough to work with in a production environment if you want anything more interesting than looking at stderr. Libraries that let you provide a logger API at time of construction are better than log.Printf, but they still fail at letting you include contextual information inside method calls.
We inject a logging interface into all our methods that take a context.Context object [1]. This allows us to push contextual information onto the stack of context objects, and then when we log we can do it at the point of failure and have access to an immense amount of useful information. Check the attached gist to see an example of how this works in practice [2].
Given that the context library originated out of Google and is now part of the stdlib in 1.7, I would love to see other libraries embrace it instead of relying on much less flexible solutions.
> No statements go by where the object is in an intermediate, invalid state.
This seems kind of misleading. Per my understanding of Go, omitted fields in a struct initialization are defaulted not reported as errors. So you're equally likely to be passing invalid state, in the two situations.
One pattern I like in Haskell, for this kind of thing, is to define a defaultConfig value that contains typical defaults and which can then be tweaked as desired.
One big advantage this has is that when some functionality is made newly configurable, you set the default to be the old behavior and existing code continues to work correctly unmodified without any additional effort.
To vendor a dependency is to store a copy of all the source code you're trying to use inside your project itself. That way, when you compile your project, you also compile the code it depends on.
Updating code you depend on is a semi-manual process - you choose to copy the latest version of the code you depend on into your project again.
This is contrast to stacks like Java, where I can give you a pre-compiled JAR file that you can link your code to.
"Vendoring" means maintaining local copies of third-party libraries and other dependencies in your local repo so exactly what you depend on is a part of your internal history. Git provides ways of doing this easily, such as subtrees.
A point of clarification for anyone skimming the original article:
> Top Tip — Libraries should never vendor their dependencies.
Peter goes on to clarify:
> You can carve out an exception for yourself if your library has hermetically sealed its dependencies, so that none of them escape to the exported (public) API layer. No dependent types referenced in any exported functions, method signatures, structures—anything.
I think this is the way to go if you're writing a library which has its own dependencies. You get a repeatable build and free yourself to change which dependencies you rely on without impacting users of your package.
There are exceptions, such as if your dependency has an init which only makes sense to run once. Loggers come to mind, where the setup should be determined by the main package. The f.Logger point in the article is friendlier to users of your package than just using log.Printf, and frees you from having to vendor logrus, for example, if you want to support structured logging.
Looks a lot like a language designed by a committee, but I generally like it.
I don't love it, like I love Python, but it does its job and it is fast.
What I really like is the defer(), the channels(having the option for asynchronous channels would be awesome), the go routines(async callback hell is getting old).
What I find completely awkward however is the enforced first letter capitalization(don't tell me how to live my life, go!), the interface{}, and the GC.
Slightly tangential, but, could someone share their experience using Go specifically for building websites?
How does Go (including Go frameworks specifically geared towards web development) compare in terms of performance, ease of development with RoR, Laravel?
Is building websites using Go a good use case or is Go better suited for building high performance microservices?
I've done a lot of ruby and go.
Honestly, I would think twice before building a major website/product API on go.
Development time is markedly slower in go, some causes off the top of my head:
- testing is way harder (ruby has some amazing mocking/stubbing/testing tooling).
- debugging is way harder. Hope you like printf.
- Json; the strict typing & struct searialization rules make dealing with Json a pain in the arse, and heavy on boilerplate
- interfacing with Sql (if you have to do a lot of it) is a pain in the arse, for similar reasons to json.
- having no stack for errors is insanely frustrating.
- templating in go is primitive
Go is amazing for services. The parallelisation primitives are fantastic, and allow you to do things that would be hard/impossible in ruby/Python.
Go is undeniably much faster, execution wise. (Although our super high volume ruby product api is at 50ms median so, it matters less than you think)
Decide what you care about most; if your prime goal is to get a product in front of customers as soon as possible, I'd pick a higher level language.
If you want to make a rock solid service that sips on resources & scales to the moon, use go.
I really enjoy using Go for building websites. But I use Go for everything, including games, frontend (instead of JavaScript), etc. There's nothing else I'd rather use. Heck, I even rewrote my resume in Go that renders HTML on frontend [0], hehe.
My experience says "don't use Go for building web applications".
Compared to something like Ruby on Rails, the development story with Go is much less batteries-included. You'll find yourself gluing together lots of components, and they're not really that friendly. Plus, for any front-end code, you'll end up using Node or whatever anyway to build assets. It's big and messy and not a good match.
Go does excel at two kind of web applications however:
- Simple single-page applications that use Websockets or simple AJAX to perform a basic task. In this case, the limitations around templating and such are less obvious, and Go is a brilliant match for Websocket clients. Think of things like status dashboards.
- JSON APIs with no front-end. Build your front-end using whatever other technology, and just fire requests at a Go app. It's pretty good at handling this, though JSON marshalling/unmarshalling is a bit stupid in Go.
I worked with both Go and Elixir but found Elixir and Phoenix better than Go for building backends for web services. I was more productive and all the awesomeness of Erlang VM made me choose Elixir. I would say give Elixir a try.
The other answers provided plenty of info on Go, so if you're looking for a new language and framework for web dev I suggest checking out elixir and Phoenix. They're inspired by ruby/rails (without some of the problems) and have many of the benefits of erlang.
>>How does Go ... compare in terms of performance, ease of development with RoR, Laravel?
The available web frameworks for Go are more comparable to microframeworks like flask. If comparing directly to RoR or Laraval, you may find some gaps. Not that they can't be solved, but there's less available out of the box. Things like:
- multiple file upload
- session handling without cookies
- built in support for a variety of authentication types and backends
The communities are also significantly smaller, so there's less experience to draw on.
Not to say you can't build websites just fine with golang, but it's doesn't seem to be a strong suit at the moment.
As you probably know (and as you can probably tell from some of the responses here), sometimes choosing languages can be like choosing a religion :-)
As a backend for a web application, Go's performance is pretty great. The Go standard library comes with a fast parallel-enabled HTTP server that already makes use of all your cores in recent Go versions. No need for things like gunicorn to take advantage of cores. There's no interpreter overhead, and there's plenty of benchmark comparisons with other languages out there on Google. I've never heard of someone not using Go as a server-side language because it wasn't fast enough :-)
Go has very robust support for creating web applications. Of course, for the frontend you will still need HTML+CSS+JS (maybe + a JS framework like Angular depending on your needs). There is a crazy experiment called GopherJS to run Go in the browser/frontend, but currently, a crazy experiment is all it is IMO...
The standard library also comes with most of the tools you'll need for defining HTTP routes (see the server examples): https://golang.org/pkg/net/http/
Personally, I've found the following third-party packages to be quite helpful with putting together HTTP server-side apps in Go:
- Gorilla mux for defining templated routes: https://github.com/gorilla/mux
- Negroni for HTTP route Middlewares: https://github.com/codegangsta/negroni
As you can see, most of what you need just comes with the standard library, which is quite professionally designed and coded (reading through their source is a pleasure). The two external dependencies I mentioned are helpful, but not a strict requirement to build a server-side app.
The main obstacle people have with using Go IMO has little to do with its ability to be used as a server-side language, and more to do with the nature of the language, and the consequences of its design choices. I think people who strongly prefer terse dynamic languages have trouble adopting/enjoying Go and its way of doing things. For instance, someone in this thread said that Go's structs and static typing makes it harder to work with JSON. You could also make the argument that this is a strength- all I have to do is declare a struct to specify what exactly I want to read from / write to JSON. Some people have complained about Go's verbosity. Sometimes they are right- certain things in Go take a little more text to express. I'm convinced that Go is a language that is more optimized for readability than for writability. You typically can't write "expressive" koans in a line of code... but your teammates probably have a higher chance (in my subjective opinion) of understanding the Go code you wrote a year after you've forgotten what you were thinking about.
I could go on and on, but now I'm just fighting the eternal language holy wars :-)
I hope I've given you a starting point for more research if you were considering Go for a server-side web application.
[+] [-] nvarsj|10 years ago|reply
1. Holy crap, this is like coding in early Java days, what the heck were the language designers smoking?! They just ignored everything! Where's my testing framework! DI?! Build system, dependency management?! WTF.
2. Holy crap, this is like coding in the early Java days! This is awesome! I can understand all golang code I read! Everything is so simple and easy. I finally get "less is more", and "worse is better"!
3. (Many months later) Oh god, I'm getting so sick of writing this test assertion in 4 lines over and over, and writing 100s of lines of mock structs. My tests are 5% substance and 95% setup. Okay let's write a junit/mockito assertion library. Oh crap, I'm having to manually wire everything everywhere and it's such a pain. Let's write a DI library. Ugh my project is getting too big and `go get` just doesn't cut it - time to use a dependency management library. Ugh, makefiles only go so far, time to write a build tool. Ugh code generation and metacoding is nonexistent, let's write our own code generation tool so we don't have to hand build 100s of types. ETC.
4. (Distant future) As golang's stubborn designers finally accept some flaws in their original thinking, they add features to make the language look a lot like another widely used language at the Googplex. Mission accomplished?
P.S. This is somewhat tongue in cheek - I do enjoy using golang day to day. It is a refreshing change :).
[+] [-] gtrubetskoy|10 years ago|reply
1. Wow, this program runs on any platform!
2. Wow, no need to free memory!
3. Wow, threads and locks are so easy to do!
Then many years later
4. Who really cares about cross-platform code if all I do is on Linux?
5. Why does this program require 4GB of ram?
6. Must I really download and install the JVM all the time, and what is it good for anyway?
Go:
1. Wow, I can write stuff that previously could only be done in C/C++, and I can do it almost as easily as writing Python or Ruby.
2. Wow, I don't need anything installed for my program to run, it just runs!
[+] [-] tptacek|10 years ago|reply
And, of course, it spawned a completely useless thread litigating Java vs. Go. Perhaps that's why it's at the top of the thread --- which means voting had a perverse effect for this topic.
I don't know what to do about this tendency in language threads on HN, but it's a real problem.
[+] [-] askyourmother|10 years ago|reply
Go still keeps it lean, and is great.
The fact it does not have hipster dev approved status is also an added bonus. The minute we see a bloated testing suite with yet another DSL, for Go, we are in trouble.
[+] [-] Mahn|10 years ago|reply
[+] [-] zzzcpan|10 years ago|reply
[+] [-] brightball|10 years ago|reply
So far, looking like a solid decision.
[+] [-] twic|10 years ago|reply
https://github.com/maxbrunsfeld/counterfeiter
[+] [-] pacala|10 years ago|reply
[+] [-] RyanZAG|10 years ago|reply
[+] [-] themartorana|10 years ago|reply
It also covers "important-to-me" features the author mentions. I haven't tried VSCode yet, but have tried all the others listed. IntelliJ is fantastic for Go.
[+] [-] MereInterest|10 years ago|reply
This one applies to every language. I was working with a python package that decided that, since `sys.argv` was available from anywhere, it should parse `sys.argv` to configure its own behavior. For a long time, their suggestion was to first parse `sys.argv` yourself, then to modify it before going into the library.
[+] [-] striking|10 years ago|reply
It was so ridiculous, someone ended up sending in a patch for the kernel to modify the command line once it had been parsed to remove the debug parameter.
https://lkml.org/lkml/2014/4/2/415
[+] [-] jzwinck|10 years ago|reply
[+] [-] bbrazil|10 years ago|reply
Where flags shine is when you've some obscure tunable deep in the dependency tree that you need to tweak (particularly in an emergency). Plumbing through potentially thousands of flags through to main is nonsensical in that scenario.
[+] [-] alexellisuk|10 years ago|reply
[+] [-] nedsma|10 years ago|reply
[+] [-] alexellisuk|10 years ago|reply
Does anyone want to submit a best-practice Go solution?
https://github.com/alexellis/xservedbyfinder
[+] [-] wtbob|10 years ago|reply
> If your repo foo is primarily a binary, put your library code in a lib/ subdir, and call it package foo.
IMHO, that's just ugly, uglier than foo/foo or foo/foolib or foo/libfoo.
I also think that anything which has commands other than a single-command project which will always be a single-command project (there are fewer of these than one might think …) should put all commands, even a single one, in cmd/.
I think that inline config objects should be used with useful zero values to try to emulate Lisp's or Python's keyword arguments: if one always needs to provide a value for each config object member, then just use arguments after all.
I think a testing library can be a great addition, since it can turn a three-line if check into a one-line assertion.
[+] [-] curun1r|10 years ago|reply
It's this kind of inflexibility in the directory structure of ones repo that really turned me off of Go. It's such a trivial thing, and yet the fact that Go lacks a level of indirection (package.json, Cargo.toml, pom.xml, etc) to map a chosen directory structure to the standard build tooling causes problems that get really annoying. For instance, there's a ton of Go repositories out there that are not go gettable because the author wanted to put source code under a src directory and hacked that together using make. And good luck with organizing any repository that contains multiple languages where go is one of them...go's "code lives at the repository root" doesn't play well with others.
It all makes me sad since Go's decentralized dependency management (i.e. go get being able to pull/build based on a meta tag) is brilliant and I always hate having to rely on a single, centralized repository to deal with dependencies.
[+] [-] zenocon|10 years ago|reply
Totally concur with this. I feel like all these people complaining about "bloated test frameworks" either haven't written a lot of tests, or are just fine with repeating themselves in test code, or they end up writing their own version of a test framework anew in every project. So much simpler and sane to grab an off the shelf solution for test code.
[+] [-] alblue|10 years ago|reply
(Disclaimer: I was the track host for Perer's talk)
[+] [-] dllthomas|10 years ago|reply
I'm not sure if this is a nit, a misunderstanding on my part, or a difference in terminology, but I think what is meant here is "value constructors" (or more commonly, just "constructors"). As I understand the term, "type constructors" construct types.
[+] [-] sagichmal|10 years ago|reply
[+] [-] hesdeadjim|10 years ago|reply
We inject a logging interface into all our methods that take a context.Context object [1]. This allows us to push contextual information onto the stack of context objects, and then when we log we can do it at the point of failure and have access to an immense amount of useful information. Check the attached gist to see an example of how this works in practice [2].
Given that the context library originated out of Google and is now part of the stdlib in 1.7, I would love to see other libraries embrace it instead of relying on much less flexible solutions.
[1] https://godoc.org/golang.org/x/net/context
[2] https://gist.github.com/justonia/f81eead323d2b23eca1c485ed8e...
[+] [-] dllthomas|10 years ago|reply
This seems kind of misleading. Per my understanding of Go, omitted fields in a struct initialization are defaulted not reported as errors. So you're equally likely to be passing invalid state, in the two situations.
One pattern I like in Haskell, for this kind of thing, is to define a defaultConfig value that contains typical defaults and which can then be tweaked as desired.
One big advantage this has is that when some functionality is made newly configurable, you set the default to be the old behavior and existing code continues to work correctly unmodified without any additional effort.
[+] [-] krat0sprakhar|10 years ago|reply
This might be a stupid question, but can someone explain to me what this means? Thanks!
[+] [-] sudhirj|10 years ago|reply
Updating code you depend on is a semi-manual process - you choose to copy the latest version of the code you depend on into your project again.
This is contrast to stacks like Java, where I can give you a pre-compiled JAR file that you can link your code to.
[+] [-] bitwize|10 years ago|reply
[+] [-] jud_white|10 years ago|reply
> Top Tip — Libraries should never vendor their dependencies.
Peter goes on to clarify:
> You can carve out an exception for yourself if your library has hermetically sealed its dependencies, so that none of them escape to the exported (public) API layer. No dependent types referenced in any exported functions, method signatures, structures—anything.
I think this is the way to go if you're writing a library which has its own dependencies. You get a repeatable build and free yourself to change which dependencies you rely on without impacting users of your package.
There are exceptions, such as if your dependency has an init which only makes sense to run once. Loggers come to mind, where the setup should be determined by the main package. The f.Logger point in the article is friendlier to users of your package than just using log.Printf, and frees you from having to vendor logrus, for example, if you want to support structured logging.
[+] [-] transfire|10 years ago|reply
[+] [-] kinkdr|10 years ago|reply
I don't love it, like I love Python, but it does its job and it is fast.
What I really like is the defer(), the channels(having the option for asynchronous channels would be awesome), the go routines(async callback hell is getting old).
What I find completely awkward however is the enforced first letter capitalization(don't tell me how to live my life, go!), the interface{}, and the GC.
[+] [-] kinkdr|10 years ago|reply
[+] [-] calcifer|10 years ago|reply
[+] [-] dineshp2|10 years ago|reply
How does Go (including Go frameworks specifically geared towards web development) compare in terms of performance, ease of development with RoR, Laravel?
Is building websites using Go a good use case or is Go better suited for building high performance microservices?
[+] [-] dalyons|10 years ago|reply
- testing is way harder (ruby has some amazing mocking/stubbing/testing tooling).
- debugging is way harder. Hope you like printf.
- Json; the strict typing & struct searialization rules make dealing with Json a pain in the arse, and heavy on boilerplate
- interfacing with Sql (if you have to do a lot of it) is a pain in the arse, for similar reasons to json.
- having no stack for errors is insanely frustrating.
- templating in go is primitive
Go is amazing for services. The parallelisation primitives are fantastic, and allow you to do things that would be hard/impossible in ruby/Python. Go is undeniably much faster, execution wise. (Although our super high volume ruby product api is at 50ms median so, it matters less than you think)
Decide what you care about most; if your prime goal is to get a product in front of customers as soon as possible, I'd pick a higher level language. If you want to make a rock solid service that sips on resources & scales to the moon, use go.
[+] [-] shurcooL|10 years ago|reply
[0] view-source:https://dmitri.shuralyov.com/resume
[+] [-] matthewmacleod|10 years ago|reply
Compared to something like Ruby on Rails, the development story with Go is much less batteries-included. You'll find yourself gluing together lots of components, and they're not really that friendly. Plus, for any front-end code, you'll end up using Node or whatever anyway to build assets. It's big and messy and not a good match.
Go does excel at two kind of web applications however:
- Simple single-page applications that use Websockets or simple AJAX to perform a basic task. In this case, the limitations around templating and such are less obvious, and Go is a brilliant match for Websocket clients. Think of things like status dashboards.
- JSON APIs with no front-end. Build your front-end using whatever other technology, and just fire requests at a Go app. It's pretty good at handling this, though JSON marshalling/unmarshalling is a bit stupid in Go.
[+] [-] iamd3vil|10 years ago|reply
[+] [-] 55tine|10 years ago|reply
[+] [-] tyingq|10 years ago|reply
The available web frameworks for Go are more comparable to microframeworks like flask. If comparing directly to RoR or Laraval, you may find some gaps. Not that they can't be solved, but there's less available out of the box. Things like:
- multiple file upload
- session handling without cookies
- built in support for a variety of authentication types and backends
The communities are also significantly smaller, so there's less experience to draw on.
Not to say you can't build websites just fine with golang, but it's doesn't seem to be a strong suit at the moment.
[+] [-] andreynering|10 years ago|reply
Go is a different story. You need to join the pieces together to make something functional. You will probably need:
- A router like [Gin](https://github.com/gin-gonic/gin)
- A [XSRF token generator and validator](https://github.com/golang/net/blob/master/xsrftoken/xsrf.go)
- An ORM like [Gorm](https://github.com/jinzhu/gorm) or [XORM](https://github.com/go-xorm/xorm)
- A template lib like the one that comes with the stdlib
- Node for front-end (ugh, this is the harder part)
- The testing library in stdlib plus maybe [testify](https://github.com/stretchr/testify)
- etc...
Many nice things are missing. Some were [shamelessy copied by other people](https://github.com/go-testfixtures/testfixtures). Some you may need to implement yourself.
The big advantages is that Go has much better performance, and run on Windows, etc.
[+] [-] pella|10 years ago|reply
[+] [-] Thaxll|10 years ago|reply
[+] [-] ereyes01|10 years ago|reply
As a backend for a web application, Go's performance is pretty great. The Go standard library comes with a fast parallel-enabled HTTP server that already makes use of all your cores in recent Go versions. No need for things like gunicorn to take advantage of cores. There's no interpreter overhead, and there's plenty of benchmark comparisons with other languages out there on Google. I've never heard of someone not using Go as a server-side language because it wasn't fast enough :-)
Go has very robust support for creating web applications. Of course, for the frontend you will still need HTML+CSS+JS (maybe + a JS framework like Angular depending on your needs). There is a crazy experiment called GopherJS to run Go in the browser/frontend, but currently, a crazy experiment is all it is IMO...
For serving dynamic content, the Go standard library comes with its own templating language and library: https://golang.org/pkg/html/template/
The standard library also comes with most of the tools you'll need for defining HTTP routes (see the server examples): https://golang.org/pkg/net/http/
Personally, I've found the following third-party packages to be quite helpful with putting together HTTP server-side apps in Go:
For testing HTTP server-side Go applications, the httptest package is quite helpful: https://golang.org/pkg/net/http/httptest/As you can see, most of what you need just comes with the standard library, which is quite professionally designed and coded (reading through their source is a pleasure). The two external dependencies I mentioned are helpful, but not a strict requirement to build a server-side app.
The main obstacle people have with using Go IMO has little to do with its ability to be used as a server-side language, and more to do with the nature of the language, and the consequences of its design choices. I think people who strongly prefer terse dynamic languages have trouble adopting/enjoying Go and its way of doing things. For instance, someone in this thread said that Go's structs and static typing makes it harder to work with JSON. You could also make the argument that this is a strength- all I have to do is declare a struct to specify what exactly I want to read from / write to JSON. Some people have complained about Go's verbosity. Sometimes they are right- certain things in Go take a little more text to express. I'm convinced that Go is a language that is more optimized for readability than for writability. You typically can't write "expressive" koans in a line of code... but your teammates probably have a higher chance (in my subjective opinion) of understanding the Go code you wrote a year after you've forgotten what you were thinking about.
I could go on and on, but now I'm just fighting the eternal language holy wars :-)
I hope I've given you a starting point for more research if you were considering Go for a server-side web application.
[+] [-] pred_|10 years ago|reply
[+] [-] dlsniper|10 years ago|reply
[+] [-] unknown|10 years ago|reply
[deleted]