Building a web service in Go
Six parts from an empty directory to a service with a gRPC contract, a REST face, generated documentation and a trace you can follow end to end. Each part leaves you with something that runs.
The tutorial, in order
Start at one. The detour at three and a half is optional and serves HTML from the same server.
-
Building a web service with go-tool-base, part 1: lifecycle and graceful shutdownService lifecycle in Go: register services with start and stop verbs, handle SIGINT and SIGTERM, and shut down gracefully with liveness checks.
Orienteering
-
Building a web service with go-tool-base, part 2: a gRPC service, with TLSDefine a protobuf contract, generate Go with buf, implement a gRPC server over a domain store, and turn on hardened TLS with mkcert and ALPN.
Orienteering
-
Building a web service with go-tool-base, part 3: a REST service, by hand and by specTwo ways to put REST on a Go service: a hand-written net/http ServeMux, and generated handlers from an OpenAPI spec with oapi-codegen.
Orienteering
-
Building a web service with go-tool-base, part 3.5: the same server, now a websiteServe HTML from the same Go HTTP server using html/template and embed, baking templates and static assets straight into the binary.
Orienteering
-
Building a web service with go-tool-base, part 4: REST for free, with the gatewayReplace a hand-written REST layer with grpc-gateway: add google.api.http annotations, generate the gateway, and delete the duplicate encoding.
Orienteering
-
Building a web service with go-tool-base, part 5: docs that write themselvesGenerate an OpenAPI v3 document from an annotated proto file and serve it from the same HTTPS server with an embedded Stoplight Elements UI.
Orienteering
-
Building a web service with go-tool-base, part 6: seeing what your service is doingAdd OpenTelemetry traces, metrics and logs to a Go service with middleware and manual spans, and get one end-to-end trace through the gateway.
Orienteering
How the pieces work
The design underneath the tutorial, and the bug that only showed up once the tracing was on.
-
Lifecycle management for when your CLI grows up into a serviceWhen a Go CLI grows into a service: ordered graceful shutdown on SIGTERM, separate liveness and readiness probes, and an opt-in restart supervisor.
Pioneering
-
The gateway that split my trace in twoWiring OTel-native observability through a gRPC service with a REST gateway, and discovering the gateway had split a single trace into two.
Pioneering
-
Telemetry that asks, and telemetry that doesn'tTwo telemetries with opposite consent defaults on one OTLP layer: consent-gated analytics for a CLI, implied-consent observability for a service.
Pioneering
Where to next
- Building a command-line tool in GoThe same framework, before it grew up into a service.