Initial GoLang Experience

Recently, I decided to try out GoLang for implementing a CRUD API, in a new project. I’ve got lots of experience in Java, Groovy, some Python, most recently.

More of my recent experience has been in Java or Groovy plus Spring Boot. I’m getting a little bored, so why not take on some learning curve and have some fun.

Requirements

Here are some of the requirements

  • Design and implement Data Model for a Domain
  • Implement CRUD API
  • Mongo database backend
  • Must have Swagger Definition to document API and facilitate generating clients in various languages.
  • Run in a Docker container
  • Can be deployed into Kubernetes

Non-functional requirements

  • Needs to be easy to consume API, in other languages.
  • Need to be able to move fast (and probably break things)
  • Must have unit tests

Nice-to-Have

  • Conservative on memory consumption.
    • This is important if I want to run things in a memory constrained environment, such as a Raspberry Pi 2B with 512 MB RAM.
  • Needs to be fun and be a learning experience

Modules & Libraries Used

Para on libraries used

Area of Functionality Module
Database access mongo-go-driver
Routing go-chi
REST API JSON Patch operations json-patch
Unit Tests testify
API Definition go-swagger

Development Experience

Para on dev experience

The Good

The language is strikingly similar to C and Java.  A background in both made it extremely easy to pick up enough proficiency in Go to achieve a starter project.

I particularly like the simplicity and clarity of the code, in GoLang.

To be fair, I also like highly opinionated frameworks with as little boiler-plate code as possible. A combination of Java 11+ or Groovy, Spring Boot, Spring Data, Project Lombok, and perhaps Spring Data REST, makes me happy, too. Honestly, sometimes the magic of Spring Boot Data REST is a little bit too much.

Go’s  ‘defer’ keyword is perhaps one of my favorite features. Delaying some action until the function exits is a fantastic was of closing resources and also logging the exit action of a function.

Just Different or Awkward

Error handling, a little bit cumbersome

Error handling was a bit different, coming from a Java background. I found it to require being more explicit in Go. 

In Java, a method could throw an exception, catch one or more exceptions, swallow them (probably a bad thing), or rethrow for the caller to handle, go requires the pattern of calling a method, evaluating whether there was an error. We can debate whether that is good or not. 

I found Go’s error detection and passing to take a little adjustment period and a little bit tedious, but certainly workable.

// I often see this pattern in the code

obj1, err := doohickey.doSomething(someArg)
if err !=nil {
   log.Println("doohickey.doSomething got error error: ", err)
   return
}
obj2, err2 := widget.doSomethingElse(otherArg)
if err2 !=nil {
   log.Println("Widget doSomethingElse returned error: ", err2)
   return
}
//...

 

JSON Response Types, to Struct Mapping

Regarding Go, JSON, and Static Types,  I found it a little bit confusing and awkward on how to handle dynamic JSON and parse that into structs in Go.

This was much easier in Groovy and Python, as they’re totally fine with dynamically converting JSON into a map of other things.

In Go, Deserializing JSON into a Struct and Serializing it back was not substantially different than in other languages.

Catching-Up in Maturity

Actually, I didn’t find anything “bad” about it.  Rather, I did find what would normally be expected.  Since Go is a relatively new language, it is still playing catch-up in some areas. 

Go Dependencies and Versioned Module Repositories

Having come from using dependency management and build tools such as Java’s  Gradle and Maven, I naturally wanted the same level of dependency management within Go.

While I was writing this,  Go Lang 1.13 came out with support for Google’s Module Proxy, having this to say:

As of Go 1.13, the go command by default downloads and authenticates modules using the Go module mirror and Go checksum database run by Google. See https://proxy.golang.org/privacy for privacy information about these services and the go command documentation for configuration details including how to disable the use of these servers or use different ones. If you depend on non-public modules, see the documentation for configuring your environment.

Concluding Thoughts

It was surprisingly easy to pick up Go Lang well enough to be productive.  I found it pleasant and fun.  Enhancing the REST API, refining the data model, generating the swagger doc, and creating unit tests were snappy and good experiences.

I will definitely learn more GoLang based on this experience.

Further reading

Leave a Reply

Your email address will not be published. Required fields are marked *