gRPC & Connect
go.putnami.dev/grpc provides a gRPC server plugin and a Connect protocol gateway for serving gRPC over HTTP/1.1.
gRPC server plugin
Basic setup
import (
"go.putnami.dev/app"
"go.putnami.dev/grpc"
)
plugin := grpc.NewPlugin(grpc.Config{
Port: 9090, // env: GRPC_PORT
})
// Register gRPC services
plugin.Register(func(s *grpc.Server) {
pb.RegisterUserServiceServer(s, &userServer{})
pb.RegisterOrderServiceServer(s, &orderServer{})
})
a := app.New("my-service")
a.Module.Use(plugin)
a.ListenAndServe()Configuration
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
Port |
int |
9090 |
GRPC_PORT |
gRPC server port |
Server options
plugin := grpc.NewPlugin(grpc.Config{Port: 9090})
// Add interceptors
plugin.WithUnaryInterceptor(myInterceptor)
plugin.WithStreamInterceptor(myStreamInterceptor)
// Enable server reflection (for grpcurl, etc.)
plugin.WithReflection(true)
// Pass raw grpc.ServerOption
plugin.WithServerOption(grpc.MaxRecvMsgSize(10 << 20))Built-in interceptors
Logging
Logs each RPC call with method, duration, and status:
import "go.putnami.dev/logger"
plugin.WithUnaryInterceptor(grpc.LoggingInterceptor(logger.Default()))Recovery
Catches panics in handlers and returns an Internal error:
plugin.WithUnaryInterceptor(grpc.RecoveryInterceptor(logger.Default()))DI scoping
Creates a DI scope per gRPC request, enabling per-request service resolution:
import "go.putnami.dev/inject"
plugin.WithUnaryInterceptor(grpc.DIInterceptor(containerContext))Connect protocol gateway
The Connect gateway exposes gRPC services over HTTP/1.1 with JSON encoding, making them accessible from browsers and REST clients.
Setup
import (
fhttp "go.putnami.dev/http"
"go.putnami.dev/grpc"
)
server := fhttp.NewServerPlugin(fhttp.ServerConfig{Port: 3000})
gateway := grpc.NewGatewayPlugin(grpc.GatewayConfig{})
// Mount Connect handlers
gateway.MountHandler("/users.v1.UserService/", userConnectHandler)
// Register on the HTTP server
gateway.RegisterOn(server)
a := app.New("my-service")
a.Module.Use(server)
a.Module.Use(gateway)Calling Connect endpoints
Connect endpoints are accessible as standard HTTP POST requests:
POST /users.v1.UserService/GetUser
Content-Type: application/json
{"id": "user-123"}Response:
{"name": "Jane", "email": "jane@example.com"}Lifecycle
Both the gRPC plugin and Connect gateway implement the standard lifecycle interfaces:
- Warmup — register services, configure interceptors
- Start — begin listening for connections
- Stop — graceful shutdown with drain
Application.Start()
→ gRPC.Warmup() — register services
→ gRPC.Start() — listen on :9090
→ Gateway.Warmup() — mount handlers
→ Gateway.Start() — ready for HTTP traffic
Application.Stop()
→ gRPC.Stop() — graceful stopRelated guides
- HTTP & Middleware — HTTP server for Connect gateway
- Plugins & Lifecycle — plugin lifecycle
- Dependency Injection — per-request DI scoping