Skip to content

Golang


The single best property of Go is that it is basically non-magical.

― Peter Bourgon

Naming conventions

  • A name should begin with a letter and cannot contain spaces. Let's keep numerics to a minimum in names.
  • If a function name starts with an uppercase letter e.g. CalculateVAT it will be exported to other packages. Lowercase function names e.g. calculateVAT won't.
  • If a name consists of multiple words, each word after the first should be capitalized e.g. firstName, shippingAddress and so on. If you're unsure if something is one word e.g. username, rather Google it to make sure (in this case it's not userName).
  • JSON variables are all lowercase with underscores replacing spaces e.g. shipping_address.
  • In Golang methods (struct that implements methods) use a short name e.g. s.
  • Avoid calling a variable the same name as packages e.g. orders as a package and orders as a variables.
  • Constants should start with an uppercase and should be encapsulated in one const e.g.
const (
    RedisKeyAccountCodeIDKey = "account-code-id-"
    RedisKeyAccountID        = "account-id-"
)

Go-utils

Sample utilities include:

  • String utils e.g. RemoveAllWhiteSpaces, IsAlphaNumeric, Int64ToString etc.
  • Struct utils e.g. UnmarshalJSON, MapParams etc. and get's mostly used by the backend framework
  • AWS SQS utils e.g. SendSQSMessage
  • Slice utils e.g. Intersection, FilterNonEmptyString etc.
  • AWS S3 utils e.g. Upload, MoveObjectBucketToBucket etc.
  • Search utils for Open Search related utilities
  • AWS Secrets manager utils e.g. GetDatabaseCredentials (from the secret)
  • Error utils for creating and logging errors
  • Address utils for cleaning and validating physical addresses
  • API doc utils for auto-generating API documentation based on the definitions of API handlers
  • And many more...

Error handling

Error handling is a little different than other programming languages e.g. Java or Python. Go’s errors are not handled by try/catch methods and do not contain stack traces. Instead, errors are values returned by functions and is essentially treated in much the same way as any other datatype. This leads to explicit error handling and a surprisingly lightweight and simple design.

Ensure that each error is returned and handled, even if it only means that it is logged.

In the go-utils module we have helper functions for logging errors.

For more documentation see https://gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/-/tree/main/errors.

ORM

An Object-Relational Mapping (ORM) is a technique that enables you to query and/or manipulate data from a DB using an object-oriented paradigm, instead of writing your own queries in its entirety.

Using an ORM has trade-offs.

Pros:

  • Sanitizing parameters
  • Simpler to write and understand for basic queries
  • Quicker to write basic queries

Cons:

  • Complex queries become convoluted and have unintended consequences
  • Sometimes slower due to overhead
  • Learning curve

Currently we're using bun (https://bun.uptrace.dev/).

We've embraced the view that simple queries, inserts, updates and deletions should use the ORM, but complex queries that need to perform optimally needs to be written in plain PostgreSQL.