Echo Router Parameters

I regularly have to look up how to create an Echo router context with (a) path parameters and (b) query parameters, so I’m making this post as a cheat sheet for my future self. Path parameters Example: /some/random/path/:id // create your context ctx := echo.New().NewContext(request, response) // add your path param ctx.SetParamNames("id") ctx.SetParamValues("foo") Query parameters Example: /some/random/path?key1=value1&key2=value2 // create your request request := httptest.NewRequest(http.MethodPost, "/some/random/path", nil) // get existing query params query := request....

2025-06-06

Go Backoff Algorithms

I ran across a blog post by Josh Bleecher Snyder today which has some beautiful backoff algorithms in Go. Capturing them here in case his blog ever goes offline. Algorithm 1 func do(ctx context.Context) error { const ( maxAttempts = 10 baseDelay = 1 * time.Second maxDelay = 60 * time.Second ) delay := baseDelay for attempt := range maxAttempts { err := request(ctx) if err == nil { return nil } delay *= 2 delay = min(delay, maxDelay) jitter := multiplyDuration(delay, rand....

2025-06-04

Playing around with trees in Golang

I was playing around with implementing Depth First Search (DFS) and Breadth First Search (BFS) in Go today. I made a tree which looked like this… 0 / \ 1 2 / \ / \ 3 4 5 6 / \ 7 8 I then made some Go code to walk the tree using DFS and BFS: package main import "fmt" // Node is a very basic struct which represents // a node in the tree....

2025-05-20

Enums in Go Part Deux - Marshaling and Unmarshaling!

My blog post from yesterday made me think… how can you marshal and unmarshal enums in Go correctly? So I modified internal/coffee/coffee.go and added a MarshalText() and UnmarshalText() methods: package coffee import ( "fmt" "strings" ) //go:generate stringer -linecomment -type=Coffee type Coffee int const ( Drip Coffee = iota // drip coffee Latte // latte Breve // breve Cappuccino // cappuccino ) func (c Coffee) MarshalText() ([]byte, error) { return []byte(c....

2025-05-15

Enums in Go

I was asked yesterday how you implement enums in Go. I didn’t know, so I spent some time this morning learning how to do it. It turns out this is ridiculously easy to do and Go has the stringer tool which makes it super simple. (stringer codegens the code which prints your enum as a string.) Example I created a repo with the following structure: go.mod main.go internal/coffee/coffee.go internal/coffee/coffee_string.go internal/coffee/coffee.go looks like this:...

2025-05-14

Go Test Parallelism

This post documents some testing I did around whether unit tests in Golang are run in parallel. TLDR: Tests in a given package run serially, unless t.Parallel() is specified. To test this, I created two files in a directory named gotest: $ ls one_test.go two_test.go // one_test.go package main import ( "fmt" "testing" "time" ) func TestOne(t *testing.T) { fmt.Println("1 starts:", time.Now().String()) time.Sleep(5 * time.Second) fmt.Println("1 ends:", time.Now().String()) } // two_test....

2024-10-18

Go sub-slice gotchas

Thanks to Julia Evan’s latest post, I learned that creating new slices by sub-slicing an existing slice has an important caveat: They can sometimes use the same backing array! 😬 This is important to understand if you mutate the sub-slice. Take the below example, wherein we accidentally mutate s1! package main import ( "fmt" ) func main() { s1 := []int{0, 1, 2, 3, 4, 5} // len == 6, capacity == 6 s2 := s1[1:5] // len == 4, capacity == 5 // Modifies both s1 and s2, because they share the same backing array....

2024-08-11

Configuring a Git pre-push hook to run unit tests

A coworker turned me onto this lovely technique the other day. You can use a git pre-push hook to run all of your Golang unit tests before pushing. To do this, make a the following file: $YOUR_REPO/.git/hooks/pre-push The file must be executable. The file’s contents should be: #!/bin/sh if ! go test ./... ; then echo echo "Rejecting commit. Unit tests failed." echo exit 1 fi Easy peasy.

2024-06-26

Running a subset of Go tests

It is often useful to run a subset of the tests in a Go project. You might do this because you only want to see test results for one package or to run tests faster. For these examples, assume your project is a Go module named examplemodule. It has the following structure: examplemodule |_ go.mod |_ go.sum |_ internal |_ foo | |_ foo.go | |_ foo_test.go |_ bar |_ bar....

2024-03-07

Max and min integer values in Golang

Today I needed to use the maximum unsigned 64-bit integer value possible in Golang. Here is a short program I wrote with some help from Stack Overflow to help me remember how to calculate these without any dependencies. package main import "fmt" const ( minUint32 = uint32(0) maxUint32 = ^uint32(0) minUint64 = uint64(0) maxUint64 = ^uint64(0) minInt32 = int32(-maxInt32 - 1) maxInt32 = int32(maxUint32 >> 1) minInt64 = int64(-maxInt64 - 1) maxInt64 = int64(maxUint64 >> 1) ) func details[numeric int32 | int64 | uint32 | uint64](name string, num numeric) { fmt....

2024-03-05