Documentation
¶
Overview ¶
Package grpcserver bootstraps a gRPC server with the SDK's cross-cutting concerns and exposes it as a worker.Runnable.
It applies the same chain of unary interceptors as the REST stack — panic recovery, trace-id injection (extracting inbound W3C trace context from gRPC metadata), structured access logging, Prometheus metrics, and errs->status mapping — then registers a health service and, optionally, server reflection. Because Server implements worker.Runnable (Name/Start/Stop), it is supervised alongside the HTTP server and background workers.
Interceptor order is recovery (outermost) -> trace -> logging -> metrics -> errormap -> application interceptors -> handler, so logging and metrics observe the already-mapped status code.
Usage ¶
srv := grpcserver.New(log, grpcserver.Config{
Addr: ":9090",
EnableReflection: true,
},
grpcserver.WithTracer(tracer),
grpcserver.WithMetrics(m.Registry),
)
srv.Install(handler) // each feature's Register owns its RegisterXxxServer call
group.Add(srv) // worker.Runnable: Start binds the listener, Stop drains
In tests, Serve runs the server on a caller-provided listener (e.g. a bufconn listener) instead of binding a TCP port.
Config ¶
- Addr: listen address, e.g. ":9090".
- ShutdownTimeout: bounds graceful drain before a hard stop (default 10s).
- EnableReflection: turns on server reflection (handy for grpcurl in dev).
- MetricsNamespace: prefixes the gRPC metric names (default "grpc").
- MaxRecvMsgSize / MaxSendMsgSize: override the 4 MiB defaults.
- NumStreamWorkers / SharedWriteBuffer: stream-serving tuning.
- Keepalive (KeepaliveConfig): server keepalive parameters and enforcement policy; zero values fall back to gRPC defaults.
Options ¶
- WithTracer(t): tracer used for trace-id injection (defaults to a no-op).
- WithMetrics(reg): registers gRPC request count/latency collectors on reg (typically the shared metrics.Metrics.Registry).
- WithUnaryInterceptors(in...): appends application interceptors, applied after the built-in ones (closest to the handler).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Addr is the listen address, e.g. ":9090".
Addr string
// ShutdownTimeout bounds graceful shutdown before a hard stop (default 10s).
ShutdownTimeout time.Duration
// EnableReflection turns on server reflection (handy for grpcurl in dev).
EnableReflection bool
// MetricsNamespace prefixes the gRPC metric names (default "grpc").
MetricsNamespace string
// MaxRecvMsgSize / MaxSendMsgSize override the 4 MiB defaults (bytes).
MaxRecvMsgSize int
MaxSendMsgSize int
// NumStreamWorkers bounds the pool of goroutines serving streams; 0 spawns
// one goroutine per stream (the gRPC default).
NumStreamWorkers uint32
// allocations under load.
SharedWriteBuffer bool
// Keepalive tunes connection liveness; zero values fall back to gRPC defaults.
Keepalive KeepaliveConfig
}
Config configures the gRPC server.
type KeepaliveConfig ¶
type KeepaliveConfig struct {
MaxConnectionIdle time.Duration
MaxConnectionAge time.Duration
Time time.Duration
Timeout time.Duration
MinTime time.Duration
PermitWithoutStream bool
}
KeepaliveConfig mirrors the gRPC keepalive server parameters and enforcement policy. Zero values are left at gRPC defaults.
type Option ¶
type Option func(*options)
Option customizes the server.
func WithMetrics ¶
func WithMetrics(reg prometheus.Registerer) Option
WithMetrics registers gRPC collectors on reg (e.g. metrics.Metrics.Registry).
func WithProtoValidate ¶ added in v0.6.0
func WithProtoValidate() Option
WithProtoValidate installs a unary interceptor that validates every request message against its buf.validate rules (protovalidate) before the handler runs. A violation is returned as errs.InvalidArgument, which the built-in error-map interceptor turns into a gRPC InvalidArgument status — so handlers need not re-check the constraints declared in the .proto.
The validator is built once and is safe for concurrent use. If the CEL environment fails to build (a misconfiguration), the interceptor fails every request with Internal rather than silently skipping validation.
func WithStreamInterceptors ¶ added in v0.6.0
func WithStreamInterceptors(in ...grpc.StreamServerInterceptor) Option
WithStreamInterceptors appends application STREAM interceptors, applied after the built-in ones (closest to the handler) — symmetric to WithUnaryInterceptors.
func WithTracer ¶
WithTracer sets the tracer used for trace-id injection. Defaults to a no-op.
func WithUnaryInterceptors ¶
func WithUnaryInterceptors(in ...grpc.UnaryServerInterceptor) Option
WithUnaryInterceptors appends application interceptors, applied after the built-in ones (closest to the handler).
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server wraps a *grpc.Server and implements worker.Runnable.
func (*Server) Install ¶
Install registers each Service on the server's registrar. Call it once, before Start, with the feature handlers — the equivalent of the REST Install function:
gs.Install(d.WidgetGRPC(ctx), d.OrderGRPC(ctx))
func (*Server) Serve ¶
Serve serves on the provided listener until Stop. It is useful for tests (e.g. a bufconn listener) and for callers that manage their own listener.
func (*Server) ServiceRegistrar ¶
func (s *Server) ServiceRegistrar() grpc.ServiceRegistrar
ServiceRegistrar returns the registrar used to register gRPC services, e.g. widgetv1.RegisterWidgetServiceServer(s.ServiceRegistrar(), handler).
type Service ¶
type Service interface {
Register(reg grpc.ServiceRegistrar)
}
Service is the registration seam a gRPC feature implements so the server need not know which concrete services exist or import their generated packages: the feature owns the generated RegisterXxxServer call, the server just hands it the registrar. It mirrors the REST rest.Handle seam, but as an interface because a gRPC service registers as a whole unit rather than per route.
func (h *Handler) Register(reg grpc.ServiceRegistrar) {
widgetv1.RegisterWidgetServiceServer(reg, h)
}