Over the last 8 months of my career at CrowdRiff I’ve made the transition from being a front-end developer to a back-end developer. When starting at CrowdRiff I was working on our client-facing interface which utilizes React/Redux, and then transitioned to being the go-to person working on the Node-side of our product. I really liked the shift to working on server-side code. When working in React I liked manipulating data, managing data, and making data show things on a screen. When I made the transition to working exclusively on then Node-side of our product, I felt like it was a great shift for me. Most importantly I was constantly challenged and learned a lot every day.
Shortly after I began working on the Node server, the team at CrowdRiff decided to make some architectural changes to the product, and the Node side of our application began to get lighter and lighter as we offloaded more of its responsibility to our API (which is written in Go). After a week or two of very little work on the node-server, I expressed my desire to join the Go team. I switched teams almost immediately and was flung head-first into a ton of challenges.
Static typing was the first adjustment I had to make when learning Go. I had worked with typing previously in Node, but only in the capacity of GraphQL. While GraphQL implements typing, it’s fairly introductory and it is used for providing the user with meaningful error responses if they send along unexpected data. While GraphQL was a great intro into the idea and key benefits of strict typing, there was a great deal to learn and get used to when working in Go.
What is my biggest take away? Strict typing is now my preferred way to program. When creating a program that is meant to last, strict typing pays off immensely. Often times in React (especially when working with state management libraries) when I return to code written months previously, I feel left in the dark with data I am working with. I often find myself wondering about the fields and the data types contained when working inside a large object. You won’t know until you run the program and investigate — or worse, when an unexpected type makes its way into your object and throws an error.
In comparison when, returning to code I’ve written in Go all the types are laid out for me. I know exactly what all data looks like at all times — leaving only the logic to reorient myself with. While this might not seem like an obvious boon to most people, I have found it invaluable when solving bugs or improving/adding to previous codebases that I have little to no experience with.
In my short experience with the language, interfaces play a huge role in how a Go application is shaped. An interface dictates what methods must be present on a class for it to be considered that interface. The most accessible example I can illustrate is the
error interface which exists in go. There are many functions in the Go standard library which make use of the
error interface. The
error interface states that in order for something to be considered an error, it must have a method of
Error() which returns a string — it can have more, but it must at least have that method. If it does, it can be used in any place that allows you to use an
Expanding on the explanation of the
error interface, we could replace every error that gets returned with our own custom error type. This custom error will have the
Error() method, which we can add new functionality to. Inside this custom
Error() method, we can add custom logic — like sending the error to a custom logger. We can also now mock this method easily, and with our custom
Error() make testing more flexible by adding testing inside of the method itself in our mocks.
Multiple Return Values
I recommend taking a leap and writing things in Go. The learning curve for is very steep, but the payoff is extremely valuable. I feel much more confident in my ability to work with and manipulate data, and being familiar with another programming language has really increased the tools I have available for implementing solutions.