transit

module
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2026 License: MIT

README

transit

Shared HTTP & gRPC transport middleware for Go services — logging, OpenTelemetry, circuit breaking, rate limiting and retry, framework-free

Go Reference Pipeline Coverage phpboyscout Go toolkit

Part of the phpboyscout Go toolkit — small, framework-free Go modules extracted from go-tool-base. Docs: transit.go.phpboyscout.uk


gitlab.com/phpboyscout/go/transit — the reusable transport middleware shared by a Go service's HTTP and gRPC edges: structured request logging, OpenTelemetry instrumentation, circuit breaking, rate limiting and client-side retry, plus the resilience primitives (a circuit breaker and a keyed token-bucket store) they are built on.

It is the middleware layer extracted from go-tool-base, which consumes it behind its pkg/http and pkg/grpc server/client constructors. It is framework-free: it carries the gRPC SDK and the OpenTelemetry gRPC/HTTP contrib instrumentation (that is the middleware's job) but nothing else — no config framework, no TUI, no go-tool-base.

Design

  • Framework-free. Dependencies are the gRPC SDK, the OTel contrib instrumentation, golang.org/x/time/rate, go/redact and cockroachdb/errors. A depfootprint_test.go guard forbids go-tool-base, Viper/Cobra, Charm and the cloud SDKs.
  • *slog.Logger at the seam. Middleware that logs takes a plain *slog.Logger, so nothing here depends on a logging framework.
  • Client and server, both transports. Each of http and grpc provides server handlers/interceptors and client round-trippers/interceptors, so a service and the clients it calls share one implementation of each concern.
  • Resilience is one package. The circuit breaker and the rate-limiter store live together in resilience; the HTTP and gRPC layers wrap them into transport-shaped middleware.

Install

go get gitlab.com/phpboyscout/go/transit

Quick start

package main

import (
	"log/slog"
	"net/http"

	transithttp "gitlab.com/phpboyscout/go/transit/http"
)

func main() {
	log := slog.Default()

	// OTel goes first: it puts the span in the context the logger reads,
	// so the access log carries trace_id and span_id.
	chain := transithttp.NewChain(
		transithttp.OTelMiddleware("my-service"),
		transithttp.LoggingMiddleware(log),
	)

	mux := http.NewServeMux()
	// mux.Handle("/", ...)

	_ = http.ListenAndServe(":8080", chain.Then(mux))
}

What's inside

  • resilience — the transport-neutral primitives: a Breaker (closed → open → half-open state machine) and a keyed token-bucket Store for rate limiting.
  • http — server middleware (NewChain, LoggingMiddleware, OTelMiddleware, RateLimitMiddleware) and client round-trippers (NewRetryTransport, the ClientChain with WithCircuitBreaker / WithBearerToken / WithBasicAuth / WithRateLimit / WithRequestLogging). The circuit breaker is client-side only — there is no server-side load shedding.
  • grpc — server interceptors (NewInterceptorChain, LoggingInterceptor, OTelStatsHandler, CircuitBreakerInterceptor, RateLimitInterceptor) and the OTelClientHandler client dial option.

Compatibility

The gRPC and OpenTelemetry dependency versions are pinned and kept in lockstep with go-tool-base (currently grpc v1.82.0, otel v1.44.0 and the gRPC/HTTP contrib instrumentation) so a service and this module share one build graph. Grouped Renovate updates keep them aligned.

What it does not do

  • No distributed state. Circuit breakers and rate limiters are per-process and in-memory: a 50 rps limit across ten replicas admits 500, and a breaker trips per replica.
  • No configuration loading. Constructors take Go structs. The config types carry mapstructure/yaml/json tags so a service can decode onto them, but transit reads no files and no environment variables, and nothing can be reconfigured after construction.
  • No *http.Client constructor. TLS settings, redirect policy and timeouts are connection policy and belong to the layer above.
  • No gRPC retry. The gRPC SDK already implements it as a service config policy.
  • No metrics, no server-side circuit breaker, no panic recovery, no timeouts, no CORS.

The full list with reasoning is at What transit does not do.

Documentation

Full guides, the middleware model, and a reference tier covering every config field and its default: transit.go.phpboyscout.uk. API reference: pkg.go.dev.

License

See LICENSE.

Directories

Path Synopsis
internal
logtest
Package logtest provides a minimal, stdlib-only slog capture handler for asserting on log output in tests.
Package logtest provides a minimal, stdlib-only slog capture handler for asserting on log output in tests.
Package circuitbreaker implements the transport-agnostic Closed/Open/HalfOpen state machine shared by the HTTP and gRPC client circuit breakers.
Package circuitbreaker implements the transport-agnostic Closed/Open/HalfOpen state machine shared by the HTTP and gRPC client circuit breakers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL