Hi there 馃憢

I do stuff with Go, Kubernetes, NATS, and other cloud native tools.

NATS & Graphql

I鈥檝e been using gqlgen at work for a few services and while I don鈥檛 normally like code generators, it does a decent job of staying out of the way. One thing I had hoped for was the ability to use the resolvers it generates with NATS instead of needing HTTP. I found an issue referencing this, and the gqlgen team mentioned they didn鈥檛 want to specifically support NATS because the resolvers were agnostic....

October 6, 2023 路 5 min 路 930 words 路 John Hooks

Custom JSON Marshaling in Go

Go鈥檚 standard library has a convenient way of handling JSON verification and default values through the Marshaler and Unmarshaler interfaces. This means we don鈥檛 necessarily need separate methods to handle this data verification/manipulation. Unmarshaler Let鈥檚 pretend our system can鈥檛 allow users that are under the age 13 and we need a default timezone. var ( ErrTooYoung = fmt.Errorf("too young") ErrTZNotFound = fmt.Errorf("invalid timezone, must be one of %v", timezones) ) type TimeZone string var timezones = [....

February 19, 2023 路 4 min 路 717 words 路 John Hooks

Custom Http Handlers Part 2

In the last post I covered a way to pass data to http handlers without using context.WithValue(). I saw another interesting way to do a type of dependency injection in a package from Jeremy called Mixer. If you own the server implementation and don鈥檛 want to import a 3rd party package you can do something similar. This doesn鈥檛 rely on generics so it is backwards compatible with older versions of Go....

October 8, 2022 路 6 min 路 1108 words 路 John Hooks

Custom Http Handlers and context.WithValue()

One thing I try to avoid when I can is using the context.WithValue(). It鈥檚 a black box map of map[interface{}]interface{}. This is obviously flexible because anything can be stored here but there are pitfalls. The documentation states you need to create your own types for keys: The provided key must be comparable and should not be of type string or any other built-in type to avoid collisions between packages using context....

September 28, 2022 路 6 min 路 1119 words 路 John Hooks

Piggy Bank

Overview Piggy Bank was born from a desire to easily store accessible secrets anywhere and not needing to expose HTTP ports for things like Vault. This project is no where near as robust as Vault (hence the name Piggy Bank) but it is desirable to be able to store secrets in the NATS KV store and have secrets be accessible to services using the bus. Authentication Authentication and authorization is done by using normal NATS auth....

August 29, 2022 路 3 min 路 431 words 路 John Hooks

Goless

Overview It鈥檚 been a goal of mine for a while to write a Kubernetes operator. I was playing with Kubeless and I didn鈥檛 like how they implemented their support for Golang so I decided to write my own. Operators Operators are a deployment of a Kubernetes controller and Custom Resource Definitions (CRDs). The controller watches in a loop for new custom resources created and then takes some action. The controller lets you extend the ability of Kubernetes without directly changing any Kubernetes code....

October 2, 2021 路 2 min 路 389 words 路 John Hooks

Bbolt Client

I use BoltDb in a few projects of mine because it鈥檚 lightweight and easily embedded in Go. However, everytime I write something that uses BoltDB I find myself writing a ton of boilerplate to complete the same tasks in every project. For example to create a bucket you need something like this: package main import ( "go.etcd.io/bbolt" "log" "fmt" ) func main() { db, err := bbolt.Open("mydb.db", 0664, nil) if err !...

May 29, 2021 路 3 min 路 501 words 路 John Hooks