Table of contents
Part of nurago, a collection of independent Go packages for backend services.
import "github.com/tecnickcom/nurago/pkg/grpcclient"
Builds a preconfigured *grpc.ClientConn for outbound gRPC calls, the counterpart of httpclient and httpretrier.
conn, err := grpcclient.New("dns:///items.internal:8074",
grpcclient.WithComponent("items"),
grpcclient.WithTimeout(5*time.Second),
)
defer conn.Close()
client := itemv1.NewItemServiceClient(conn)
A plain ClientConn
New calls grpc.NewClient and returns its result. Every behaviour is added through interceptors and dial options, so generated stubs, health clients and any other gRPC tooling work unchanged, and there is no wrapper type to thread through the code.
Create the connection once and share it: it is safe for concurrent use and multiplexes calls over HTTP/2.
What every call gets
| Step | What it does |
|---|---|
| Trace propagation | copies the traceid from the context into the x-request-id metadata, generating a UUIDv7 when there is none |
| Logger | one outbound entry per RPC with target, service, method, grpc_type, grpc_code and timing |
| Default deadline | gives a unary call without a deadline the one set by WithTimeout, 1 minute by default |
| Your interceptors | WithUnaryInterceptor and WithStreamInterceptor, in order |
The trace ID is the same value the HTTP client sends in X-Request-ID, so a request that crosses both transports keeps one ID in every log.
The default deadline matters because a gRPC call without one waits forever. Streams are exempt.
Logging levels follow the status code
An RPC is logged at error level only when its code maps to a 5xx status: UNKNOWN, DEADLINE_EXCEEDED, UNIMPLEMENTED, INTERNAL, UNAVAILABLE, DATA_LOSS. NOT_FOUND, INVALID_ARGUMENT and the other application outcomes are logged at info, or at debug when debug logging is on.
That keeps error-level alerting on failures of the downstream service rather than on lookups that legitimately found nothing.
At debug level, unary messages are dumped as protobuf JSON, redacted, and omitted above WithMaxDumpSize. A failed RPC logs its error through the RedactFn at every level.
A stream is logged once, when it ends. As grpc-go requires, read a stream until it returns an error or cancel its context; otherwise it is never logged and its resources are never released.
TLS unless you say otherwise
TLS with the system root certificates and TLS 1.2 as the minimum is the default. WithTLSConfig sets a private CA or a client certificate, WithCredentialsBundle uses Google default, ALTS or xDS credentials, and plaintext needs an explicit WithInsecure.
Combining more than one of those is an error from New (ErrConflictingTransportSecurity), so a configuration that sets both TLS and plaintext cannot silently pick one.
Retries belong to grpc-go
WithRetryPolicy compiles a policy into the default service config, and grpc-go executes it:
grpcclient.WithRetryPolicy(grpcclient.RetryPolicy{
Methods: []string{itemv1.ItemService_GetItem_FullMethodName},
MaxAttempts: 3,
InitialBackoff: 100 * time.Millisecond,
MaxBackoff: time.Second,
BackoffMultiplier: 2,
RetryableCodes: []codes.Code{codes.Unavailable},
})
The native mechanism is transport-aware in ways an interceptor cannot be. It uses exponential backoff with jitter, honours the call deadline, and stops once response headers arrive, so a stream is never replayed after the server has answered. grpc-go also retries, transparently and independently of any policy, a call that never reached the server application.
Scope each policy to methods that are safe to repeat. grpc-go caps attempts at 5; WithMaxCallAttempts changes the cap. For logic the service config cannot express, wrap the call with retrier.
Instrumentation
WithInstrumenter adds the dial options of a grpcutil.ClientInstrumenter. prometheusgrpc and opentelgrpc implement it, and one value of either can be passed to both the server and the client.
Dependencies
Reaches google.golang.org/grpc, google.golang.org/protobuf, google.golang.org/genproto/googleapis/rpc, and golang.org/x/net, x/sys and x/text.
Links
- Reference documentation
- Source code
- The guide: /docs/grpc-services/
- Serving gRPC: grpcserver
- The HTTP counterparts: httpclient, httpretrier
- All nurago packages