Summary of How I write HTTP services in Go after 13 years:
- The NewServer constructor - big constructor that takes all dependencies as parameters. returns
http.Handler. configures its own muxer and calls out to routes.go. includes setting up middleware, CORS, logging.
** Long argument lists - type safety in arguments.
- Map the entire API surface in routes.go
- func main() only calls run() - run() returns an error and accepts OS fundamentals as parameters for easier testing. background context is created in main but all other context handling is done in run.
** Gracefully shutting down - pass context through and check it at each level.
** Controlling the environment - use
flags.NewFlagSet inside run. make a replacement os.Getenv for tests and pass that to run (or the real thing for main).
- Maker funcs return the handler - creates a readable closure for each.
- Handle decoding/encoding in one place - for JSON/XML encode/decode.
- Validating data - single method interface with
Valid(ctx context.Context) (problems map[string]string)
- The adapter pattern for middleware - take an
http.Handler and return one.
- Sometimes I return the middleware
** An opportunity to hide the request/response types away - keeps global space clear.
- Use inline request/response types for additional storytelling in tests
- sync.Once to defer setup - anything expensive during handler setup, defer to the first time it’s called to improve overall app startup time.
- Designing for testability
** What is the unit when unit testing? - multiple levels of options from
run() down to calling individual handler functions.
** Testing with the run function
** Waiting for readiness - loop on hitting a /healthz endpoint until the server has started.
golang
Really good writeup of Roc’s decision to rewrite their compiler in Zig (original version written in Rust).
roc
rust
zig
making a video out of an audio file and a single image:
$ ffmpeg -loop 1 -i cover.jpg -i audio_file.mp3 -c:v libx264 -tune stillimage -c:a aac -shortest -pix_fmt yuv420p output.mp4
Note: the image must have a height that’s divisible by 2.
linux
“the hedgehog is too proud a bird to fly without a kick” - Russian proverb
quotes