DEV Community

How I Built an API with Mux, Go, PostgreSQL, and GORM

Ali Spittel on January 04, 2018

I've been seeing a lot of discussion about how fast Go is. According to the Benchmark Game Go is much faster than Node, somewhat faster than Java, ...
Collapse
 
tangzero profile image
Jairinho • Edited

Nicely done. Simple and clean.

But I've some tips for you:

  • The GOPATH and GOROOT setup isn't necessary. GOPATH default is $HOME/go since Go 1.8. You can check where your GOPATH and GOROOT points to with "go env". Only need to set the PATH:


export PATH=$HOME/go/bin:/usr/local/bin:$PATH

  • You must validate the return of json.NewEncoder(w).Encode(&resource). Always check your return errors.

  • db.Create, db.First, db.Find, etc can fail, so db.Error must be checked.

if err := db.Create(&resource).Error; err != nil {
    // error handling...
}

Keep learning and sharing! :)

Collapse
 
aspittel profile image
Ali Spittel

Interesting -- go install and godep didn't work before I set the GOPATH and GOROOT -- I would guess it is because of brew install instead of following the website directions.

I would check the errors on a bigger app -- the chances of this one being used are next to zero! More a learning experience than anything.

Thanks for the tips!

Collapse
 
imthedeveloper profile image
ImTheDeveloper

How did you find the learning curve with GO? It's a language that seems to be picking up in popularity as of late and I'm just itching for a use case to start messing around with it. At the moment I'm pretty entrenched in Node and JS ecosystem.

Collapse
 
aspittel profile image
Ali Spittel • Edited

I found the learning curve really small, though I think having C++ experience lowered it a lot. It did, in a lot of ways, feel like an Express app with more middleware built in though.

Collapse
 
andres profile image
Andrés Pérez • Edited

I would suggest using Sprintf instead of concatenating your strings for the database connection, nonetheless, good job! working with Go is amazingly fun.

Collapse
 
tangzero profile image
Jairinho • Edited

In this case, I think os.ExpandEnv is a better solution:

db, err = gorm.Open(
        "postgres",
        os.ExpandEnv("host=${HOST} user=${USER} dbname=${DBNAME} sslmode=disable password=${PASSWORD}"))
Enter fullscreen mode Exit fullscreen mode
Collapse
 
aspittel profile image
Ali Spittel

Oh awesome, didn't know about this -- will definitely try it!

Collapse
 
andres profile image
Andrés Pérez

If you're defining the environment variables, yeah, sure.

Collapse
 
aspittel profile image
Ali Spittel

Agreed!

Collapse
 
umakanthdiwakar profile image
Umakanthan D

Nice article. GO/Postgres is the technology which we use to develop microservices in our organization. Choice here was on chi framework, due to its native support for GO context (available from GO 1.7) and for Postgres we use pgx for its ultra-fast performance, able to snapshot a few thousand records in a second or so. But then pgx is more of a low-level API resulting in a lot of boiler-plate code. We developed a pgx GO code generator to automate developing all the database access code. We recently opened up the generator code at github.com/umakanthdiwakar/pgx-daogen. It basically generates the entire database access code by reading the metadata from Postgres catalog schema. In a way encourages database first development, but saves a lot of effort. Generated code is pure GO and pgx, with no dependency on our library.

Collapse
 
assertnotnull profile image
Patrice Gauthier

Great article!
I want to point though things to consider though, specially related to web development.
Node or Javascript in general is not made for computational work so the benchmark test doesn't reflect the general problem faced by web development. WebAssembly will help a lot with computational load. To be fair, Node has more of a memory problem when handling a lot of data, I'm facing exponential memory usage at work but this is a different problem.
I think that Golang is really suited for fast and easy to develop portable shell apps (Docker is based on it) and a better contender for web app would be Elixir because of the high availability of 99.9999999% since it's running on Erlang. Think Elixir as Ruby functional programming style. Both Elixir and Go uses a scheduler for concurrency and Elixir Processes are similar to Go routines. Since it's running on Erlang, Elixir processes are made to crash and recover and allows hot swapping of code.

I've looked at both of them in the need of designing a better global distributed high availability service than the current one we have.

References:
smashingboxes.com/blog/choosing-yo...
blog.codeship.com/comparing-elixir...
thecodebarbarian.com/getting-start...

Collapse
 
rhymes profile image
rhymes

Thank you Ali!

I was reluctant about Go in the beginning because I'm not in love with its syntax (but I'm starting to like it) and its concurrency model (though it's winning me over :D) but I still plan to build something with it and as you said is not that hard to pick up (though I don't have your C++ experience)

My biggest concern is that I don't know if I can introduce it into the client's stack, even if I'm the only developer for this or that service it's a little bit easier to find Python / Ruby devs than Go ones. It's a pity because for services that are not super IO-bound Go would be perfect :-)

A side note: I stopped using curl and started using httpie, my brain is thanking me :D

Collapse
 
axxa3000 profile image
axxa3000

When deploying to Heroku, how do you get the .env variables?

Working find in local.

Thanks.

Collapse
 
axxa3000 profile image
axxa3000

For fast deployment in Heroku, 2 minor changes.

Procfile:
web: helpful-coding-resources-api-master

rest-api:

db_url := os.Getenv("DATABASE_URL")
db, err = gorm.Open("postgres",db_url)

to connect to DB.

This is for the new people trying Go+Heroku, that work for me, hope
to save u some time.

great tut! thanxs Ali.

Collapse
 
aspittel profile image
Ali Spittel

I did this!

Collapse
 
hosembafer profile image
Rafael Hovhannisyan

When I started (3 months ago) learning Go, I planned to build simple API, and in this case, I found a lot of problems with code structure and package choosing.

But I have found Gogs, which is the biggest project I can find at the time written in Go. And there are a lot of examples of good code in Go, from which I started to learn. If you want to continue your introducing into Go, I suggest you read/learn/change/run the code of Gogs

Collapse
 
ovasquezbrito profile image
oduber vasquez brito

Hello! Congratulations. How do I insert a date field with GO?

Collapse
 
ovasquezbrito profile image
oduber vasquez brito

Hello! Congratulations. How do I insert a date field with GORM?

Collapse
 
ovasquezbrito profile image
oduber vasquez brito

This is the error:
parsing time \"\"2018-06-05\"\" as \"\"2006-01-02T15:04:05Z07:00\"\": cannot parse \"\"\" as \"T\"