Hacker News new | ask | show | jobs
A quick and easy way to setup a RESTful JSON API in Go (github.com)
58 points by ant0ine 4431 days ago
4 comments

The "Countries" example does not look correct to me. Go maps aren't safe for concurrent use (such as parallel REST API requests in this case) and need to be protected with a sync.RWMutex or similar, although it might work safely in some special cases (I'm not sure).
You're right, the example does have a glaring bug - and I completely agree with you, examples should not include incorrect code.

Just to clarify, maps can be read concurrently without locking as long as you're not writing to them. As soon as any concurrent operation might make changes to the map (as the example does) you need locking, preferably a sync.RWMutex (a sync.Mutex will also work but will be way less efficient for no good reason).

I'm pretty sure the map here is not the important part. The example demonstrates how to use the rest interface to talk with a store. The actual implementation of the store is up to you.
I think it's important for example code to also be correct. If it needs to gloss over some details, put them in a function call that isn't defined.

Using an unprotected map here is incorrect.

Absolutely! Example code affects programming style and teaches people. It should be correct (and in good style), this is probably very much underrated.
Fair point, examples should be correct even on the part that is not the primary focus of the example. I’ve added a RWMutex to the "users" example, other examples improvements will come soon. https://github.com/ant0ine/go-json-rest-examples/commit/6983...
How does this differ from Tiger Tonic ( https://github.com/rcrowley/go-tigertonic )?
I once read the you aren't supposed to use ORMs in Go. I am not sure why. Does anyone have an idea?
Many gophers hate magic. ORMs are specifically magic, and therefore not very popular with many gophers.

Many gophers have a lot of experience in other languages with ORMs and have been burned by them on many occasions.

I like to say - ORMs make the easy stuff easier, and the hard stuff harder. If you're only doing really simple object storage and your data model easily fits with the model the ORM expects, then it's not too bad. If you EVER want to deviate from that model (and you'll ALWAYS end up wanting to deviate from that model), then you are gonna have a bad time.

There actually are plenty of Go ORMs: https://code.google.com/p/go-wiki/wiki/Projects#ORM (there's probably many that aren't on this list)

Many gophers prefer their code to be more obvious and more under their control. Writing a little SQL never hurt anyone, and Go's SQL package is pretty good. Personally, I like http://github.com/jmoiron/sqlx - you have to write SQL statements still (I consider that a good thing), but it removes the boilerplate of getting data in and out of structs.

I'm not sure I see the "magic" in trivial compilers.
Well said. My biggest problem with ORMs in the past boils down to them being "leaky abstractions". They work fine for simple create/update/deletes, but get into trouble with foreign keys, indexes, "group by", advanced queries, etc.
We're using an internally developed ORM in Go and it saves us a lot of time.

Pros:

- Less typing, which means less bugs.

- Type-checked queries, although this is technically not part of the ORM. We have a custom tool which statically examines the code creating ORM queries, checks the types of the output and lets you know of potential errors (e.g. the field you're querying on does not exist anymore). Writing the same tool for SQL would be incredibly difficult.

- No need for long ugly SQL strings in code (well, except for the ORM implementation itself).

- Easier refactoring. If we make changes to a model, the ORM makes the schema modifications for us (with some limitations - e.g. if you rename a field you have to tell the ORM the old name, so it renames the field in the table instead of creating a new one). Coupled with type-checking this is god-send.

- Complete SQL database abstraction (database/sql does not provide that - placeholders, quotes, etc... vary by database driver).

- SQL / NoSQL / KV-store / whatever transparency. We have SQL drivers for sqlite, postgres and mysql, as well as drivers for mongodb, the GAE datastore and redis. Of course, some drivers have limitations, like the NoSQL ones can't perform JOINs, but we still get incredible flexibility. We had one app running on GAE with a data model which was a good fit for the datastore. Some months later, a few requirements were added and moving to a relation database was the best solution. So we spun off a Google Cloud SQL instance, migrated the data and started using JOINs for the new features, while the previous code continued to work unchanged.

- App Engine / vanilla Go cross platform (well, you'd also need our full web framework for that, but the ORM is one of the key components). We have some applications running in GAE. If they ever get too costly to run on GAE we can just execute three of commands and deploy it to our own servers (and by "three" I mean the exact number: one command to move the ORM data from the datastore to the new database, another one to move the stored blobs from the GAE blobstore to S3/GCS/filesystem and another one to deploy the app to the new server).

Cons:

- Overhead. Negligible in most cases, but when it matters we can drop down to raw queries.

At the end of the day, I think using an ORM or raw database queries is just an engineering decision you have to make depending on your project constraints, not on the language you're using.

It's not that you are not supposed to use ORMs in Go. ORM take away control from you and your code. ORMs are a blackbox.

I prefer writing plain SQL when dealing with databases. And in Go, this can be done with a few lines of code [1].

[1] http://stackoverflow.com/questions/11353679/whats-the-recomm...

One reason might be that there weren't any ORMs around that would qualified to be called such for other languages, last time I checked. https://github.com/jinzhu/gorm is probably still the most popular choice.
I think http://github.com/coopernurse/gorp is currently the one winning hearts and minds.

Though as jmoiron points out http://jmoiron.net/blog/gos-database-sql/ if you're looking for a Go version of ActiveRecord it isn't going to be achievable any time soon.

Why would I use Go instead of Ruby/Python/nodeJS?
Go has a ton of things going for it! I suggest Googling for more info, but a couple of my favorite features:

* I can use go fmt to format my code and it'll look nice. So many people use go fmt that most code bases are very easy to dive into. They all follow the standard!

* No magic! You write what you want and the whole formality of the thing forces you to write better code. May be a placebo effect, but I find myself writing less buggy code in Go.

* Compile to static binary you can just drop and run -anywhere-. No rvm gemsets, no rbenv, no bla bla bla - you want your code running, period.

So you can have a maintainable codebase.
Well that's just nonsense.

You can have maintainable and unmaintainable codebases in any language.

Clearly you have never run across the same program, first in Perl, and then in Python, and felt the tangible differences in maintainability between the two implementations.
Go provides performance headroom allowing you to develop low-latency applications without extraneous effort and premature optimization.