writing-microservices-in-go-01

In Hemingway’s A Farewell to Arms, the heroic archetype Frederick Henry stated of martinis, ”I had never tasted anything so cool and clean. They made me feel civilized.” The days of Hemingway might have been absent of APIs and coding languages, but had he been around in the modern era, he would have probably said the same of Go, the unique, refreshing, future-friendly language taking the API world by storm.

Today we take a look at this trendy and unique language. By the end of this piece, we will have discussed the basic mechanics of this developer favorite — we’ll even produce a rudimentary API to show how easy it is to get running.

Go? Go Where?

The Go language — also known as “golang” — began its life in 2007, as a passion project of Robert Griesemer, Rob Pike, and Kem Thompson, then employees of Google. While the language started off as an experiment rather than as a project to replace other languages, early versions showed so much promise that the project quickly took on a life of its own.

Because the language loosely derived its syntax from C, a popular language in development communities, and added functionality through type safety, garbage collection, and a large library of packages, the language quickly took on the reputation of being user-friendly. This much-lauded and highly effective user-friendly nature quickly made Go the language of choice for hobbyist developers, and by 2009, the language entered into the public consciousness.

As development has continued, adoption of Go as a standard for frameworks has exploded. This constant development and innovation positioned Go as the language of experimentation, making it prime for future-proofing and “develop for later” approaches to the development lifecycle.

Why Go, Though?

Simply put, Go is a wonderful language that incorporates the best of two worlds. Because it was developed primarily with the C programming language in mind, many long-time developers will be intimately familiar with the methodologies and terminologies inherent in the system. These similarities are in style more than substance, however, meaning that what limitations the C derived commands and syntaxes have in their native languages are all but eliminated from Go.

While its similarities with other languages is one world of positive mention, Go has become a beast in its own right, providing many extensible and experimental feature sets for further development. Go provides a seamless system for development that removes many of the most time-intensive calculations of other languages. Included with the basic packages of golang are currency primitives, dynamic language development, and a basic Net/HTTP package for handling client/server HTTP implementations in a resource and time efficient manner. Go compiles surprisingly quick, and uses basic standard libraries and packages to do some amazing things.

Blog Post API Lifecycle

Rudimentary API – The Server

Now that we’ve heard how easy it is to implement Go, let’s construct basic snippets of code for a demonstration. Today, we’re going to be creating a very rudimentary API design to respond to a query in a specific way, utilizing the fast and lightweight RESTful style of API development.

In Go (as with most languages), your first step in building a Web API or microservice is to create a basic server. First, we need to establish which packages and services will be automatically loaded on startup.

In the snippet above we’ve defined a few very important things. By stating the first line, “package main”, we establish that what we’re running is an executable command (executable commands in Go always use “package main”). Secondly, we declare a few additional packages we want to utilize, specifically “fmt”, “net/http”, “log”, “html”, and “io/ioutil”. Note that while we’re not going to utilize all of these in this piece of code, it is acceptable practice to toggle them all for future development needs.

Now we need to add a few lines of code to define what it is that we want our code to do.

We’ve added two main sections to this code, each with very important roles to play in the execution. This entire code snippet will, when run, spin up a server on port 8080 of all interfaces (to connect, we will utilize http://localhost:8080). In order to do this, we needed to define two functions.

The first function, “func handler”, utilizes the http.ResponseWriter and http.Request calls to return connection to the server with a string of text. This text, “Welcome, %!”, then utilizes the r.URL.Path[1:] string to append the connection URL to the text returned. Thus, when user “John_Smith” connects to his personal portal located at “http://localhost:8080/John_Smith”, he will receive “Hello, John_Smith!” as a response indicating his connection success.

A second function, “func main”, utilizes the http.ListenAndServe to direct all traffic to port 8080 utilizing the default handler. This handler then manages the traffic flowing into port 8080 throughout the APIs’ defined functions or routes. This allows our code to work in concert with the server, directing traffic and managing the flow of data.

Extending Usefulness

What we have now is a basic web server. It’s a very good web server, but in terms of APIs, it’s utterly useless. An API by its very definition is an interface between users and applications — this communication is necessarily a two-way street, where requests are handled and responded to with specific rules.

Now that we have a server, let’s turn it into an actual API and make it do something for us. So far, we’ve developed a basic server that can host files and data for access by clients. Let’s allow a client to request the build name, number, and date when prompted with the “about” invocation.

Three parts have been appended to the bottom of our code. The first, “type Message struct”, is a structure-defining element. All data needs to be given structure through defined variables, otherwise, the data is considered to be in raw format. We have defined our structure as “Text string”, meaning that whatever data is to come will be delivered as a plain text string rather than formatted into currency, dates, or other formats.

Secondly, we’ve added a rather lengthy section which will respond to its invocation with a text string message stating “Welcome to the SandovalEffect API, build v0.0.001.992, 6/22/2015 0340 UTC.” The third addition is related to the second, and is a panic state — that is, it is the defined response when a faulty invocation is made. This chunk of code will allow http://localhost:8080/about/ to return the string above, and return an error code with logging when a fault connection or request is made.

Conclusion – Simplicity to Complexity

The golang gopher - the cool new programming language on the block

The Golang gopher – the cool new programming language on the block

What has been shown so far is incredibly simple, but it’s actually some of the most important code you’ll ever seen in golang. Go is a language that is fundamentally extensible, and if you learn a single, simple function, such as invoking a call that gives simple data, this data can then be formatted, stored, manipulated, deleted, and so forth. Something as simple as calling the “about” function could be used to reference stock numbers or store pricing, for example.

Further functionality can be founded in the standard lib for just about anything you could want to do. For instance, utilizing the “filepath.Walk” function, you can scan a filesystem and output the files at the root of a folder and display the directory structure in text form. The “gzip” function allows for compression and decompression of the gzip format specified in RFC 1952.

The “regexp” function allows for regular expression search over the contents of a system or file. For massive complexity, the “runtime” package allows for coordinate operations between the user and Go’s runtime system to control subroutines and interfaces.

Thankfully, the Go system of extensibility is rather intuitive. By utilizing a package system akin to Linux, golang largely moves past the need to build heavy and time-consuming frameworks, allowing for quicker learning, production, and implementation. This relative simplicity and resultant lower overhead has made it easier for companies and individuals to build microservices and APIs — a practice that is becoming ever more important in the modern business era.

About Kristopher Sandoval

Kristopher Sandoval is a web developer, author, and artist based out of Northern California with over six years of experience in Information Technology and Network Administration. He writes for Nordic APIs and blogs on his site, A New Sincerity.

  • Jesus Galvan

    The return should be inside the about function.
    And it looks like the about function would not get called in last example.

  • Hello Kristopher,

    I think the function about is missing a } in the final so the correct code will be:

    func about (w http.ResponseWriter, r *http.Request) string {
    m := Message{“Welcome to the SandovalEffect API, build v0.0.001.992, 6/22/2015 0340 UTC.”}
    b, err := json.Marshal(m)
    if err != nil {
    panic(err)
    }
    return string(b)
    }

    • Kristopher Sandoval

      Sorry about that – it’s rather easy to mess up code copying it from interface to dashboard to editor and back! I’m sure I misplaced a few additional variables somewhere along the way, but the point remains the same.

      Thanks!

      Kristopher

  • Jurij Koch

    http.HandleFunc(“/”, handler)
    http.ListenAndServe(“:8080”, nil)
    http.HandleFunc(“/about/”, about)
    maybe you should call the handlefunc for “about” before listening :)

    • travisspencer

      Fixed

  • teejayvanslyke

    Hi Kristopher! Thanks for the overview. It was a great refresher after I first dove into Go’s HTTP library last week.

    What’s your favorite Mux library for Go? There are so many and it’s hard to know where to look as a newbie.

    • travisspencer

      On a recent project I was involved in, we wrestled with the idea of using Go. One of the biggest factors in this decision was the availability of dependencies (e.g., a Web API library). For that dependency in particular, I didn’t find so many, only Gorilla Web Toolkit really stood out (http://gorillatoolkit.org/pkg/mux). Are there others? Can you list a few of the ones you’ve come across?

    • Kristopher Sandoval

      Hey there!

      I would have to say, hands down, Gorilla. There’s a lot of cross-operational functions there, so unlike some of the other solutions, you don’t end up trying to decide between aesthetics/ease of use and functionality. I think that’s definitely something most programmers struggle with, so having a solution for that in a compact form is definitely preferable.

      Thanks for the comment!

      Kristopher

      • teejayvanslyke

        Thank you for the response. I’ll check it out!

    • Also be sure to check out Echo, it’s a newer package…But it’s fast fast fast =) https://github.com/labstack/echo

  • Wang Yandong

    Type of http.HandleFunc’s handler is not func(ResponseWriter, *Request) string but func(ResponseWriter, *Request).
    I don’t think this example will pass the build.

    ======

    http.HandleFunc(“/about/”, about)

    func about (w http.ResponseWriter, r *http.Request) string {

    m := Message{“Welcome to the SandovalEffect API, build v0.0.001.992, 6/22/2015 0340 UTC.”}
    b, err := json.Marshal(m)

    if err != nil {
    panic(err)
    }

    return string(b)
    }

    • travisspencer

      Thanks, Wang! Typo fixed.

  • Great post! Have you seen Koding’s Kite? It’s a good microservice framework for Go. https://github.com/koding/kite – I also blogged about my experiences with it here: http://www.shift8creative.com/posts/flexible-service-oriented-architecture-in-go

  • Joshua Stewart

    I’m not sure if this is intended of the following, but the format verb should be %s, correct?

    func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, “Welcome, %!”, r.URL.Path[1:])
    }

    • travisspencer

      Thanks, Joshua, for catching that detail. It’s fixed in the text above.

  • travisspencer

    Some others had this question too. It’s a fair one, but the point of this article was really only meant to be an intro and an eye opener. Given that we keep getting this question though, I think we need to write a more advanced Go tutorial on microservices and APIs. For that, we need a serious Go expert, which I know I’m not and I think @kristophermsandoval:disqus is also still striving to become. Perhaps that expert is you, @ulugbekrozimboyev:disqus. If so, please hit @billcdoerrfeld:disqus up with a draft for a future post! That would be killer. Or perhaps you can refer readers to some other sources that you’ve found helpful which go deeper than this one. That would also be much appreciated by the community, I’m sure :)

  • Madars Vi

    Guys check out Enduro/X framework, it also offers microservices framework for Go. Every service (or set of services) are separate executables, controlled by application server. The services invoke each other by using underlying middleware. Framework provides ability to run distributed transactions across the multiple services. Binddings for Go: https://github.com/endurox-dev/endurox-go and application server by it self is here: https://github.com/endurox-dev/endurox
    Very basic sample here: https://github.com/endurox-dev/endurox-go/tree/master/tests/02_basic_string_call/src Client app call the server app, by sending some string to server and receives answer back.