Golang’s Standard Superpowers

You've probably already heard "go is the greatest thing since sliced strings". But you are still not sure the hype is really accounted for. Well, for starters, take a look at how it compares to NodeJS, and how it measures up to Java - the Cobol of our generation. If you haven't already, take a look at the golang.org website.

Still unsure?

Go is about run-time robustness and efficiency. Efficiency when coding, debugging, compiling and running it. Being compiled and statically typed Go projects are less prone to run-time errors. Being compiled also means no run-time dependencies (ssh the executable to the machine and run it, done!). It also has easy and maintainable concurrency in its design. You want the function "expensiveCalc()" done concurrently? simply type "go expensiveCalc()". This, combined with closures, makes Go a very powerful language for computation intensive tasks. Combining concurrent tasks can be done through channels that allow you to create event driven applications that don't get messy by design. Coming from a NodeJS world (where I've shed tears when debugging promises, async and callbacks) this makes me really really really happy. The last thing, and the main reason I love Go, is its modern standard library with embedded super-powers that make building applications a snap.

To demonstrate my last point let's write a micro-service in Golang that creates an HTTP service and returns some JSON. I'm assuming you have installed the compiler and set up your GOPATH.

First things first, let's import the packages we will use in our service, we will need http support, logging support and a json encoder/decoder. As it turns out, Golang has great out-of-the-box support for this:

package main

import ( "net/http"; "log"; "encoding/json")

We will use the http package, to register a handler function to a pattern ("/thing"). Then, we will start an HTTP server with a given address and a handler with ListenAndServe. We will leverage go's log package, to log and clean-exit when things go wrong.

func main() {
  http.HandleFunc("/things", things)
  log.Fatal(http.ListenAndServe(":9090", nil))

That's it for configuring and starting our Http server! You'll have to agree that for a compiled language this was dead simple!

We will need a way to model data in our application. Go's struct type provides typed collections of fields that we can use to model objects within our application. Let's create a "Thing" object with a Value field:

type Thing struct {
  Value string

Let's now write our handler:

func things(w http.ResponseWriter, r *http.Request) {
  thing := Thing{Value: "Hello"}

This function will create a new Thing object ({Value: "Hello"}) and json-encoded it in the response. We are done. However, our application is quite useless. We can expand it with a few lines to at least return a JSON encoded array of key values queried in our URL. We will modify our handler, and modify our Thing struct:

func things(w http.ResponseWriter, r *http.Request) {
  // will return a map[string][]string
  query := r.URL.Query() 
  thing := Thing{Values: query}

// modify the struct to map to the Query() return type
type Thing struct {
  Value map[string][]string 

That's it! You can now use your application by running "go run main.go". Let's make a GET request to it:

curl http://localhost:9090/things?key=value&keys=1,2,3

Which will return:

{ Values: { key: ["value"], keys: ["1,2,3"]} } [\code]

Here's your full application:

Where to go from here? Go by Example is one of the best resources, along with the Golang-Book

Want to know more about Go? Find more about Go at the Go FAQ.