gRPC Server

Kashvi includes a production-ready gRPC server that runs alongside the HTTP server on a separate port. It ships with a health-check service, server reflection, and pre-wired Prometheus metrics.

Configuration

.env
GRPC_PORT=9090    # default: 9090

What starts automatically

When you run kashvi run, both servers boot:

go
๐Ÿš€ Kashvi HTTP  on :8080  [env: local]  [workers: 8]
๐Ÿ”Œ Kashvi gRPC  on :9090

At shutdown (Ctrl+C), the gRPC server drains in-flight RPCs before exiting.

Built-in interceptors (applied automatically)

OrderInterceptorWhat it does
1RecoveryCatches panics โ†’ returns INTERNAL instead of crashing
2LoggingLogs every RPC: method, duration_ms, code
3Prometheusgrpc_server_handled_total, grpc_server_handling_seconds

Built-in services

Health (grpc.health.v1.Health)

Always returns SERVING. Test with:

# brew install grpcurl
grpcurl -plaintext localhost:9090 grpc.health.v1.Health/Check
# โ†’ { "status": "SERVING" }

Server Reflection

Enabled automatically โ€” grpcurl works without proto files:

grpcurl -plaintext localhost:9090 list
# โ†’ grpc.health.v1.Health

Registering your own service

go
// pkg/grpc/server.go  โ€” add after reflection.Register(srv)
mypb.RegisterUserServiceServer(srv, &UserServiceImpl{})

Or call grpc.Start() manually and register before the goroutine runs:

go
grpcSrv, lis, _ := kashvigrpc.Start(config.GRPCPort())
mypb.RegisterUserServiceServer(grpcSrv, &UserServiceImpl{})

Standalone gRPC server (CLI)

Run the gRPC server without the HTTP server:

kashvi grpc:serve

Adding a custom interceptor

Edit pkg/grpc/server.go โ€” add to chainUnary(...):

go
grpc.NewServer(
    grpc.UnaryInterceptor(
        chainUnary(
            recoveryInterceptor,
            loggingInterceptor,
            metricsInterceptor,
            myAuthInterceptor,  // โ† add here
        ),
    ),
)

Prometheus metrics

gRPC metrics are available on the existing /metrics endpoint alongside HTTP metrics:

go
grpc_server_handled_total{grpc_method="/grpc.health.v1.Health/Check", grpc_code="OK"} 7
grpc_server_handling_seconds_bucket{grpc_method="...", le="0.01"} 7