#go
12 posts

Go’s tooling is an undervalued technology

Go uses decentralized package management, or rather, module management. There is no central module manager or module registration, no external repository to trust and no need for an internal one.
Read more

Go’s tooling is an undervalued technology

  • As it has no external dependencies, you can build the latest version of Go using just the compiler in seconds and cross-compiling only needs setting a couple of environmental variables (GOOS and GOARCH).
  • Go uses decentralized package management, or rather, module management. There is no central module manager or module registration, no external repository to trust and no need for an internal one.
  • Since a module only needs to be hosted on a reachable network with valid HTTPS certification, with the network path becoming the name, there is no worry over duplicating popular module names.
  • Dependencies are cryptographically locked to versions. So, an upstream source cannot change a published module for those depending on it.
  • As each dependency is a single point of failure, Go checks with a module proxy before fetching the dependency. If you prefer, there is a GOINSECURE option for experimentation to avoid HTTPS certification.

Full post here, 6 mins read

5 advanced testing techniques in Go

Use test suites - develop tests written against an interface for all implementations of that interface. Carefully consider interfaces before exporting them and avoid creating a hard dependency between a consumer package and your own.
Read more

5 advanced testing techniques in Go

  • Use test suites - develop tests written against an interface for all implementations of that interface.
  • Carefully consider interfaces before exporting them and avoid creating a hard dependency between a consumer package and your own. To avoid exporting an interface, use an internal/package subtree to keep the interface scoped to the package.
  • Don’t export concurrency primitives, especially channels and the sync package. Also, add documentation on whether a struct or package is safe for concurrent access by multiple goroutines.
  • Use net/http/httptest to speed up tests and run them in parallel more easily, without binding to a port or setting up a server.
  • Use a separate _test package inside the foo/ directory of the package you want to test, rather than the default package pkg. This is a workaround for cyclic dependencies, prevents brittle tests and lets you see what it is like to consume your own package.

Full post here, 8 mins read

How we improved the observability of a Go project

Add comprehensive info-level logging coverage to make each step of processing more observable. Structure logging with log levels using the logrus package to eliminate noise and improve searchability within logs, and impose consistency.
Read more

How we improved the observability of a Go project

  • Add comprehensive info-level logging coverage to make each step of processing more observable. Structure logging with log levels using the logrus package to eliminate noise and improve searchability within logs, and impose consistency.
  • Create a structured error type to include a generic map of data. This will help you diagnose what exactly went wrong at the top level when error handling, indicating which errors are fatal and which indicate you should retry processing.
  • Use Go’s context package, threading it through all request handlers and message processors for greater control over your services, making for a more reliable shutdown in case of new deployment or scaling events.
  • Combine the detailed errors and logging into a common abstraction to reduce code repetition. You can add functions for creating errors and logs with basically the same interface, in turn using the context data.
  • Add service-level indicators (SLIs) for high-level functions in asynchronous processing to reveal end-to-end latency of different kinds of processing to end-users.

Full post here, 6 mins read

How we implemented domain-driven development in Golang

Some learnings from Grab’s implementation of the principles of domain-driven development (DDD) and idiomatic Go.
Read more

How we implemented domain-driven development in Golang

Some learnings from Grab’s implementation of the principles of domain-driven development (DDD) and idiomatic Go.

  • Work closely with business/domain experts to gather knowledge on the required functionality and flow of what you are building.
  • Break down this knowledge into different problems that need to be solved. Categorize these problems into bounded contexts and subcontexts (read here to know more about it).
  • Use these contexts to identify dependencies in the code & in the team. Identify the building blocks (value objects and entities) to further break down the functionality and flow.
  • Create interfaces to abstract the working logic of a given domain (i.e. repository).
  • Identify domain events and let them provide the relevant useful information to the user in other domains. This enables the independence of different classes.
  • Use a common language developed with the domain experts and apply it consistently in discussions and coding (for instance, to name classes and methods).

Full post here, 5 mins read

Top security best practices for Go

You should validate user entries (using native Go packages or 3rd party packages) not only for functionality but also to avoid attackers sending intrusive data.
Read more

Top security best practices for Go

  • You should validate user entries (using native Go packages or 3rd party packages) not only for functionality but also to avoid attackers sending intrusive data.
  • Use HTML templates to cover the vulnerability of XSS. You can use the html/template package to sanitize JavaScript executables.
  • Ensure each database user has limited permissions, that you are validating user inputs and that you are using parameterized queries to protect yourself from SQL injections.
  • Make the best use of Go’s crypto package to encrypt sensitive information.
  • Enforce HTTPS communication and implement in-transit encryption even for internal communication.
  • Remember that error messages and error logs can expose sensitive information. Use the native library in Go for logs or third-party options like logrus, glog or logo.

Full post here, 6 mins read