Creating gRPC Clients
1. Creating Client Connection
Example: Modern client connection (Go)
conn, err := grpc.NewClient("dns:///users.internal:50051",
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
)
if err != nil { log.Fatal(err) }
defer conn.Close()
client := userv1.NewUserServiceClient(conn)
| API | Status |
|---|---|
grpc.NewClient v1.63+ | Current recommended API (lazy connect) |
grpc.Dial DEPRECATED | Legacy — eagerly connects |
2. Setting Dial Options
| Option | Purpose |
|---|---|
WithTransportCredentials | TLS or insecure |
WithDefaultServiceConfig | JSON for retry/LB policy |
WithKeepaliveParams | Keep-alive ping config |
WithChainUnaryInterceptor | Compose interceptors |
WithUserAgent | Custom UA string |
WithDefaultCallOptions | Per-call defaults (size, compressor) |
3. Creating Service Stub
| Step | Detail |
|---|---|
| Constructor | NewXClient(conn) for each service |
| Reuse | Stubs are cheap; share across goroutines |
| Thread safety | Connection and stubs are safe for concurrent use |
4. Configuring Transport Security
| Option | Use |
|---|---|
credentials.NewTLS(cfg) | Standard TLS |
credentials.NewClientTLSFromFile | Pin server cert |
insecure.NewCredentials() | Local dev only |
5. Setting Connection Timeout
Example: Bounded dial via per-RPC context
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
res, err := client.GetUser(ctx, &userv1.GetUserRequest{Id: "u1"})
| Note | Detail |
|---|---|
NewClient connects lazily | First RPC triggers handshake |
| Use context deadline | Bounds connect + call together |
6. Using Keep-Alive Settings
Example: Client keep-alive
kp := keepalive.ClientParameters{
Time: 10 * time.Second,
Timeout: 3 * time.Second,
PermitWithoutStream: true,
}
conn, _ := grpc.NewClient(addr, grpc.WithKeepaliveParams(kp), ...)
| Field | Meaning |
|---|---|
Time | Idle interval before sending ping |
Timeout | Wait for pong before closing |
PermitWithoutStream | Ping even with no active RPCs |
7. Closing Connections
| Action | Detail |
|---|---|
conn.Close() | Cancels active RPCs; releases resources |
| Pattern | defer conn.Close() at app top-level |
| Anti-pattern | Closing per-RPC — destroys multiplexing |
8. Implementing Connection Pooling
| Strategy | When |
|---|---|
| Single connection | Sufficient for most workloads (HTTP/2 multiplex) |
| Pool of N connections | Very high QPS (>10k) where one TCP saturates |
| Round-robin pool | Manual atomic.Add index across []*grpc.ClientConn |
9. Handling Connection Errors
| Status Code | Likely Cause |
|---|---|
| Unavailable | Server down, network partition, DNS fail |
| DeadlineExceeded | Connect or RPC timed out |
| Canceled | Caller canceled context |
| Unauthenticated | Missing/invalid TLS or token |
10. Using WithBlock Option
| Option | Status |
|---|---|
grpc.WithBlock() DEPRECATED | Only applied to Dial. Use context deadline on first RPC with NewClient |
grpc.WaitForReady(true) per-call | Wait for ready instead of failing fast |