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.

10 posts7-part tutorial

The tutorial, in order

Start at one. The detour at three and a half is optional and serves HTML from the same server.

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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.

  1. 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
  2. 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
  3. 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

Everything, newest first →