Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This is a good place to ask this (because Go posts attract a lot of commenters, even those who dislike Go and like some other language):

Which language/framework would you choose today for writing WebServices? Preferably with the following characteristics: static type (or at least static analysis), easy deployment (ex, generates a single binary like in Go), supports concurrency very well, is small/simple, has good tooling and debug support, and is fun to write. Go (except for good debug support)? Elixir (dunno how good it is with deployment and debugging)?



Java. Static types (less sophisticated than state of the art, more sophisticated than Go), fairly easy deployment (you can easily make a package with everything except the JVM, so it's your one binary + /usr/bin/java + libjli + lib{c,dl,pthread,z}), concurrency is state of the art (whether old-school threads-and-locks with java.util.concurrent, actors with Akka, fibres with Quasar, whatever you like), is a quite small and simple language with a standard library that admittedly rivals any European capital for size, complexity, fascinating details, layers of history, and alleyways that stink of piss, tooling and debugging is state of the art, and fun, well, Java's really more golf than base jumping.

Documentation, performance, and community are varied but often excellent.

Libraries and frameworks abound (some are even quite good). Perhaps surprisingly, everyone seems to have settled on JAX-RS/Jersey as the way to write REST APIs. It's what's in the EE spec, so it's what guys in polyester suits in banks are writing, and it's what's in Dropwizard, so it's what gals with bright blue hair in startups are writing. The only real alternative is Spring MVC, which is really very similar, but requires that you buy into Spring.

Probably not the answer you wanted. But not bad for a language that's a day older than Braveheart.


If going down this route, I'd probably look into using Kotlin with dropwizard, rather than Java. Maybe it's just me, but the amount of code you have to write in Java that really should be auto-generated (and often is, by an IDE) is absurd.

I've not toyed extensively with Kotlin yet, but so far it does look like a "modern Java done right". Most of the code you don't actually need to write, or read -- like getters and setters that just get and set.

And it's close enough to plain Java that there's little overhead, and not a whole new language -- like with Scala, or Clojure.


Yes! Kotlin and Ceylon are both really interesting, as attempts to judiciously add and remove features to/from Java, to produce something recognisable, and easy for the unwashed masses (ie me) to pick up, but still much better.

My only concern is that they don't have much depth of community or history yet. That can be a very interesting and rewarding time to pick up a language, but it can also be a drag on actually getting things done.


True. Then again, that code that your IDE generated for 10 year old Java doesn't really have a community that refreshes it either, and it sits there in your VCS, and takes up space in code reviews etc.


I would choose Go. It comes with an excellent built-in package net/http (https://godoc.org/net/http) that quickly allows you to setup a web service. An Go's mechanic (?) of implicit satisfaction of interfaces allows you to do some really cool things. One of the gripes about Go seems to be error handling, and your code ends up with a whole bunch of 'if err != nil { stuff }'.

Matt Silverlock (http://elithrar.github.io/article/http-handler-error-handlin...) talks a bit about how you can use some of Go's strengths to create a web services without any frameworks or packages that aren't built-in. Go and net/http is very powerful and allows you to do very much without needing any external packages.

If it was up to me, I would write the service in Go and run it in a container somewhere. But the container is not required :)

Go has been a bit lacking in debugging options previously as you said, but lately cool projects like godebug https://github.com/mailgun/godebug and Delve https://github.com/derekparker/delve have been released, making it possible to debug programs better.


Yes, just using built-in packages, and not depending on too many third-party packages is definitely attractive to me. The code full of "if err != nil" is an issue that I've also noticed. However, I'm hopeful that this may actually remind me to be more exhaustive in error handling.

Why did you mention the container? How kind of benefits would you be getting from a container for Go?


A container is just useful. But given Go's static binaries, you could also just ship the binary over to a server and be up and running. But it's nice to just have a container with all the bits/config inside that you can just copy over. The benefits of a container are the same for any language.


Elixir is what I would choose. I think of deployment as a one time cost. So, the cost of exrm+docker solves your build problem and then your deployment is like a "single binary". (except its a single docker container which is sufficient for me, maybe not for you.)

As I understand it the go runtime must pause to resolve atomic locks for all the goroutines running. So, when you're doing a dozen goroutines in your app it's not a problem, but you couldn't do thousands of them. Meanwhile elixir processes can handle millions of processes without blocking like that, and that plus the ... strength... of immutable memory (vs. shared in go) makes me like elixir, especially when concurrency is important. (I don't consider go to be a concurrent language in this regard.)

Good tooling and debug support: I can't compare the two languages in this regard, go seems to have good library support. Elixir has excellent tooling and debug support (REPL mainly, and really nice error messages), and I think Elixir has good library support too.

Fun to write: So far for me, Elixir wins this hands down. Go is running neck and neck with Erlang in the "not very fun to write" range for me.

Of course this is all personal opinion.

The only objective thing is- if you need real concurrency and to build a distributed system (go doesn't even have the concept of language support for Nodes) then Elixir is the way to go.

If on the other hand you need max compiled speed on a single node, the Go wins hands down.


No such thing as Elixir processes. They're Erlang processes because they're constructs of the EVM. Whether or not you consider the latter fun to write is irrelevant.


Of course. I don't think anyone is pretending like Elixir isn't built on top of erlang.


Thanks! The point about immutability is important. Based on the comments I've been seeing on HN, I had a feeling that Docker brings its own set of problems. But, it may be worth checking it out.

> I think Elixir has good library support too.

I guess the support will be even better if you consider using Erlang libraries.


Plain Erlang is also nice.


I learned erlang first, years ago. I absolutely fell in love with it. Somewhere when I wasn't writing a lot of erlang code, it crusted over and now the erlang syntax bothers me. While elixir is more than a syntax, yes, that is part of its value for me.

To me, in my head, symbolically Elixir and Erlang are the same language, the concepts I'm using most of the time are representable in both. I just find Elixir more fun and easier to write quickly.


Scala/Spray. Wonderful full-fledged type system, complete with a strongly typed model of HTTP (so that e.g. ContentType is well-typed, and takes a well-typed model of a MIME type, not just a String). Excellent concurrency support, very fun, all the JVM tooling/debug support. Deployment needs a tiny bit of fiddling - I recommend building with maven and using the maven shade plugin, then you get a standalone jar that you just need a JVM to run.

The unique selling point is that your routing is defined in a DSL that's almost as nice as the config file most systems would use - but it's ordinary Scala, well-typed and refactorable in the normal way because everything's just code. And because the type system has higher-kinded types you can use typed wrappers to represent cross-cutting concerns, with the lovely for/yield sugar for composing them. E.g. you can have database-session-in-view but in a principled way: you have a wrapper type that represents an operation that needs to happen in a database transaction, and if you want to compose two or more such operations you use the for/yield sugar, and it's all refactor-safe and you can tell which unit tests need a database (fake or real) because it's right there in the type. And at the route level you either have a marshaller that handles your wrapper completely transparently, or your own directive that works exactly like the built in ones because again, it's all just code. You can click through to the source of the directives and see how they're implemented, not just magic annotations like with JAX-RS. If you want to get super mind blowing you can even use for/yield to compose together directives to make a custom directive.


i've been partial to Go for the past few years. My toolkit is mainly comprised of martini for the web framework, gorm for the database handling (also includes auto migrations which is awesome!) and heroku for hosting (they have native Go support now) or even dokku on your own VPS

The software I write is primarily used in advertising, and Go allows me to write the software quickly and is able to handle a large load as you can see here: http://imgur.com/zpkjwlh

There is some overhead with Martini and Gorm, but the ease and speed of development more than make up for the performance loss


You might also want to take a look at Negroni since it's supposed to be more idiomatic. There's a blog post about this by the author himself.

http://codegangsta.io/blog/2014/05/19/my-thoughts-on-martini...


I've used it with mux, and have detailed my experience here: https://www.dougcodes.com/go-lang/martini-to-gin-back-to-mar...

Negroni and Mux are great to use, and typically I will go back and refactor the code to squeeze out any extra performance if it's needed and the project has proven its worth, but Martini has middleware that is hard to beat and easy to set up to get proof of concepts out the door.


I think it is not so much about "good debug support", or "easy deployment". It is really about what YOU, as an individual, without any regard to who wrote what language reimplementing its slice of CLisp, can do with a given language.

You're a rockstar in C? go for it, and just dockerize the result. You're a Ruby ninja? fine, and Capistrano the result (or just dockerize it). You're a Go ninja? why not, and then scp the result + restart the process via ssh. You're a CLisp expert? fuck yeah, and then reinject the new code directly in the running process. Just because you can. Who will stop you?

Have fun, that is the real point.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: