You will have to be a programmer if you’re going to be a network engineer in the future,
they say. I don’t agree, but it surely helps you do your job. But what language should you learn? Perl? (no) Python? (maybe) Ruby? (perhaps) Every time I say something about learning Python, a little voice on Twitter says Or Go!
. Go? Go. And so, sucker that I am, I gave it a go (pun intended). TLDR: I think you should, too.
The Go Programming Language
The name Go feels like it should be a terrible word to search for on the Internet because it’s so short, but searches actually work remarkably well if you use Google Search. Compare the results of a search for “go if then else” from Bing and Google below; I’ll let you guess which is which:
Maybe Google has learned from my search history. So, what’s important to know? Go is:
- Open source. The source code is readily available and can sometimes be helpful to figure out what’s going on.
- Free, obviously
- Pretty fast
- Multi-platform (Linux, OS X, Windows for starters)
- A compiled language
- Strongly typed
- Capable of concurrency and multithreading
As a Perl programmer used to the extremely lazy (and sometimes dangerous) automatic casting of variable between data types as needed, writing in a strongly typed language takes a little more work than I like. However, the benefits of doing so are well established, and in the end so long as things work, I’ll live with it.
The Go Playground
Go to http://golang.org/ and on the front page there’s a little Hello World
script that you can click a button to run it. Go on, try it. Now edit the code and run it again. That’s pretty handy, and in fact the Tour (an introduction to the Go language) includes editable, runnable examples on every page. Want to share code with a friend? Add it to http://play.golang.org/ then click the Share button; the website takes a snapshot of the code and generates a unique URL you can send out (with obvious security implications, but to try out an algorithm with help, it’s fantastic). It’s a small feature, and really it’s a browser feature rather than a Go feature as such, but it’s a really nice way to introduce people to the language.
Why Go? Why Now?
Here’s what got me thinking that I should try Go finally. I have been playing around writing a REST API client so I can do some automation, and my previous efforts have been in Perl and Python. While I’m very comfortable with Perl, and I love the way JSON data can be handled, the web connection side of things was beginning to feel kind of clunky and I’m never truly happy with my code. I started by looking at the Hello World code (because who doesn’t?):
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
Even I can understand that, so I started searching for more examples and came across something like this to grab a web page:
package main
import (
"fmt"
"net/http"
"io/ioutil"
"os"
)
func main() {
response, err := http.Get("http://golang.org/")
if err != nil {
fmt.Printf("%s", err)
os.Exit(1)
} else {
defer response.Body.Close()
contents, err := ioutil.ReadAll(response.Body)
if err != nil {
fmt.Printf("%s", err)
os.Exit(1)
}
fmt.Printf("%s\n", string(contents))
}
}
This feels oddly like familiar territory. It’s not a lot of code to get a web page downloaded and print the output, and that includes some basic error handling. I looked at this and thought If it’s as simple as that to get a web page, writing my REST API client is going to be simple!
Of course, I know better now, but still, there’s a certain elegance to the language. Plus — and this is a huge win over Python for me personally — it uses curly braces rather than indentation to define code blocks, which makes me feel all warm and fuzzy. What’s not to like?
Cross-Compilation
I wrote a (very) basic REST client as planned, then I wrote a couple more. The first – with some generous Twitter help from Kale Blankenship (@vCabbage) extracted the data of interest from a JSON response. JSON turned out to be an interesting change from Perl, and I’ll maybe talk about that in another post, but with Kale’s help it suddenly made sense and I was able to progress past my own stupidity. The next couple of clients were built on the same code base, take a bunch of command line arguments to reformat and turn into an API call, then, in the first implementation – receive a plain text response which can be printed back to the user. It’s the first step in migrating some of my tools from being fat clients run directly by the user, to being thin clients calling a REST API, and the results being calculated in the background by the server, which is also where the data resides. This way I can make the tool’s functionality available to users on their local machine without them needing access to the data. My users, however, are a mix of linux, OS X and Windows users, and this is where Go just came into its own.
Go 1.5 has made cross-compilation so easy it’s ridiculous. Here’s how I build a client for OS X:
env GOOS=darwin GOARCH=amd64 go build my_rest_client
This command sets the environment variables GOOS (Go OS) to the target operating system, and GOARCH (Go Architecture) to the target CPU architecture. The rest of the command (go build my_rest_client
) tells go to build the client. In actuality, since I’m running Go on OS X 64-bit, I don’t really need to define the OS and Architecture as they’re already known. Still how about 64-bit linux on Intel?
env GOOS=linux GOARCH=amd64 go build my_rest_client
Yup. Want to guess how compiling a client for Windows looks?
env GOOS=windows GOARCH=amd64 go build my_rest_client
I gather that before Go v1.5 it wasn’t that easy, so I’m grateful that I came to the language now! The list of valid GOOS and GOARCH values includes freebsd/netbsd/openbsd, plan9, solaris and architectures include 386, amd64, arm / arm64, and ppc64, so yes, Raspberry Pi ARM linux builds are possible.
With a simple shell script, one command builds executables for all my target clients. Compared to helping people install Python or Perl and getting all the necessary modules installed, this is positively a dream.
My 2 Bits
Go is not, shall we say, as easy a move as I’d like it to be. As a lazy perl programmer, moving to a strongly-typed language makes things interesting. However, I’ve managed to achieve quite a few things all using core libraries, where Perl would have had me installing multiple modules and many tens of dependencies along the way. I’m going to try and stick this one out, because it seems like Go has the potential to do some cool stuff with relatively little effort.
In a future post, I’ll run through my basic REST API client code, and hopefully the relative simplicity will inspire one more person to give Go a chance. We’ll see if I still like Go in a year, but for now — with very shallow exposure to the language — it gets two thumbs up.
Kale came back on Twitter with an optimized version of the above (See? TMTOWTDI!) which I like:
With his additional helpful comments, you can see it in the playground: https://play.golang.org/p/4SpfD4bGe5
I prefer to use javascript (JS) and nodejs. JS also uses curly braces rather than indentation to define code blocks. Plus overwhelming number of libraries and package manager. JS works in browser, server-side (nodejs), mobile and noSQL database like mongodb. Recent version (ES6) has all the missing parts.
Loving Go myself as a network engineer! Always looking for opportunities to learn more and apply Go to my networking world. BTW – A great place to practice Go is http://exercism.io/
Great post. Really enjoyed reading that. Thanks very much!