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.
CalculateVATit will be exported to other packages. Lowercase function names e.g.calculateVATwon't. - If a name consists of multiple words, each word after the first should be capitalized e.g.
firstName,shippingAddressand 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 notuserName). - 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.
ordersas a package andordersas a variables. - Constants should start with an uppercase and should be encapsulated in one
conste.g.
const (
RedisKeyAccountCodeIDKey = "account-code-id-"
RedisKeyAccountID = "account-id-"
)
Go-utils
- Go-utils (https://gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/) is a set of utility functions used between all of our Go projects. It's a Go Module, so it can be easily added to a Go project.
Sample utilities include:
- String utils e.g.
RemoveAllWhiteSpaces,IsAlphaNumeric,Int64ToStringetc. - Struct utils e.g.
UnmarshalJSON,MapParamsetc. and get's mostly used by the backend framework - AWS SQS utils e.g.
SendSQSMessage - Slice utils e.g.
Intersection,FilterNonEmptyStringetc. - AWS S3 utils e.g.
Upload,MoveObjectBucketToBucketetc. - 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.