Features
gRPC extension capabilities
GRPC Interface
The extension exposes a comprehensive GRPC interface for server management:
type GRPC interface {
RegisterService(desc *grpc.ServiceDesc, impl interface{}) error
Start(ctx context.Context, addr string) error
Stop(ctx context.Context) error
GracefulStop(ctx context.Context) error
AddUnaryInterceptor(interceptor grpc.UnaryServerInterceptor)
AddStreamInterceptor(interceptor grpc.StreamServerInterceptor)
RegisterHealthChecker(service string, checker HealthChecker)
GetServer() *grpc.Server
IsRunning() bool
GetStats() ServerStats
GetServices() []ServiceInfo
Ping(ctx context.Context) error
}Full gRPC Server
A production-ready gRPC server running on a dedicated TCP port with support for all four RPC types:
- Unary -- single request, single response
- Server streaming -- single request, stream of responses
- Client streaming -- stream of requests, single response
- Bidirectional streaming -- stream of requests and responses
// Register your protobuf service before app.Start()
server.RegisterService(&pb.MyService_ServiceDesc, &myServiceImpl{})TLS and Mutual TLS
Serve over TLS with configurable certificate, key, and CA files. For zero-trust service-to-service authentication, enable client certificate verification:
forgeGrpc.NewExtension(
forgeGrpc.WithTLS("server.crt", "server.key", "ca.crt"),
forgeGrpc.WithClientAuth(true), // require client certificates (mTLS)
)Health Checks
The standard grpc.health.v1.Health service is registered by default. Register service-specific health checkers:
type HealthChecker interface {
Check(ctx context.Context) error
}
server.RegisterHealthChecker("my-service", &myChecker{})Health probes check all registered services and report per-service status.
Server Reflection
Enabled by default for debugging with grpcurl, grpcui, and other reflection-aware tools:
# List services
grpcurl -plaintext localhost:50051 list
# Describe a service
grpcurl -plaintext localhost:50051 describe myapp.Greeter
# Call a method
grpcurl -plaintext -d '{"name":"Alice"}' localhost:50051 myapp.Greeter/SayHelloInterceptors
The extension automatically configures interceptor chains for both unary and streaming RPCs:
Built-in Interceptors
| Interceptor | Purpose |
|---|---|
| Logging | Logs every RPC call with method name, duration, and status code |
| Metrics | Emits counters and histograms for RPC calls (request count, latency, errors) |
| Tracing | Propagates distributed trace context via OpenTelemetry |
| Recovery | Catches panics in handlers and returns gRPC Internal status instead of crashing |
Custom Interceptors
Add your own interceptors:
// Unary interceptor
server.AddUnaryInterceptor(func(
ctx context.Context, req interface{},
info *grpc.UnaryServerInfo, handler grpc.UnaryHandler,
) (interface{}, error) {
log.Printf("Method: %s", info.FullMethod)
return handler(ctx, req)
})
// Stream interceptor
server.AddStreamInterceptor(func(
srv interface{}, ss grpc.ServerStream,
info *grpc.StreamServerInfo, handler grpc.StreamHandler,
) error {
log.Printf("Stream: %s", info.FullMethod)
return handler(srv, ss)
})Keepalive
Configurable server keepalive parameters with enforcement policies for misbehaving clients:
Keepalive.Time-- ping interval for idle connectionsKeepalive.Timeout-- wait time for ping responseKeepalive.MinTime-- minimum time between client pings (enforcement)Keepalive.PermitWithoutStream-- allow pings even without active streams
Message Size Limits
Configurable maximum receive and send message sizes (default 4 MB each):
forgeGrpc.NewExtension(
forgeGrpc.WithMaxMessageSize(16 * 1024 * 1024), // 16 MB
)Concurrent Stream Limits
Cap the number of concurrent streams per connection with MaxConcurrentStreams to prevent resource exhaustion.
Service Info and Statistics
Query registered services and runtime stats:
// List registered services and methods
services := server.GetServices()
for _, svc := range services {
fmt.Printf("Service: %s\n", svc.Name)
for _, method := range svc.Methods {
fmt.Printf(" %s (client_stream=%v, server_stream=%v)\n",
method.Name, method.IsClientStream, method.IsServerStream)
}
}
// Runtime statistics
stats := server.GetStats()
fmt.Printf("Connections: %d, RPCs started: %d, Failed: %d\n",
stats.TotalConnections, stats.RPCsStarted, stats.RPCsFailed)Sentinel Errors
| Error | Meaning |
|---|---|
ErrNotStarted | Server has not been started yet |
ErrAlreadyStarted | Server is already running |
ErrServiceNotFound | Requested gRPC service not registered |
ErrInvalidConfig | Configuration validation failed |
ErrStartFailed | Server failed to start (e.g. port in use) |
ErrStopFailed | Graceful shutdown failed |
ErrHealthCheckFailed | Health check probe failed |
How is this guide?