This document covers the core client and server functionality in gRPC-Go, including client connection management, server creation and lifecycle, dial options, server options, and service registration.
ClientConn represents a virtual connection to a conceptual endpoint. It manages name resolution, load balancing, connection pooling, and RPC invocation.
type ClientConn struct {
// Has unexported fields
}// NewClient creates a new gRPC client connection (recommended)
func NewClient(target string, opts ...DialOption) (*ClientConn, error)
// Deprecated: Use NewClient instead
func Dial(target string, opts ...DialOption) (*ClientConn, error)
func DialContext(ctx context.Context, target string, opts ...DialOption) (*ClientConn, error)Example:
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
// Basic connection
conn, err := grpc.NewClient("localhost:50051",
grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("failed to connect: %v", err)
}
defer conn.Close()
// With TLS
creds, _ := credentials.NewClientTLSFromFile("ca.pem", "")
conn, err := grpc.NewClient("example.com:443",
grpc.WithTransportCredentials(creds))
// With multiple options
conn, err := grpc.NewClient("dns:///myservice:8080",
grpc.WithTransportCredentials(creds),
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"}`),
grpc.WithKeepaliveParams(keepalive.ClientParameters{
Time: 10 * time.Second,
Timeout: 3 * time.Second,
}))// Invoke performs a unary RPC
func (cc *ClientConn) Invoke(ctx context.Context, method string, args, reply any, opts ...CallOption) error
// NewStream creates a new stream for streaming RPCs
func (cc *ClientConn) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error)
// Close tears down the ClientConn and all underlying connections
func (cc *ClientConn) Close() error
// GetState returns the connectivity state
func (cc *ClientConn) GetState() connectivity.State
// WaitForStateChange waits until connectivity state changes
func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState connectivity.State) bool
// Connect causes all subchannels to attempt to connect (experimental)
func (cc *ClientConn) Connect()
// ResetConnectBackoff resets backoff timers and causes immediate reconnect attempts (experimental)
func (cc *ClientConn) ResetConnectBackoff()
// Target returns the target string
func (cc *ClientConn) Target() string
// CanonicalTarget returns the canonical target string
func (cc *ClientConn) CanonicalTarget() string
// GetMethodConfig gets the method configuration for a specific method
func (cc *ClientConn) GetMethodConfig(method string) MethodConfigGenerated code uses this interface, allowing for easier testing and mocking.
type ClientConnInterface interface {
Invoke(ctx context.Context, method string, args any, reply any, opts ...CallOption) error
NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error)
}Dial options configure the client connection behavior.
type DialOption interface {
// Has unexported methods
}
// Credentials
func WithTransportCredentials(creds credentials.TransportCredentials) DialOption
func WithPerRPCCredentials(creds credentials.PerRPCCredentials) DialOption
func WithCredentialsBundle(b credentials.Bundle) DialOption // Experimental
// Insecure (for testing only)
func WithInsecure() DialOption // Deprecated: use WithTransportCredentials(insecure.NewCredentials())
// Connection parameters
func WithConnectParams(p ConnectParams) DialOption
func WithBackoffConfig(b BackoffConfig) DialOption // Deprecated
func WithBackoffMaxDelay(md time.Duration) DialOption // Deprecated
// Timeouts and idle
func WithIdleTimeout(d time.Duration) DialOption // Experimental
func WithTimeout(d time.Duration) DialOption // Deprecated
func WithBlock() DialOption // Deprecated
// Authority and naming
func WithAuthority(a string) DialOption
// Service config
func WithDefaultServiceConfig(s string) DialOption
func WithDisableServiceConfig() DialOption
// Resolvers and balancers
func WithResolvers(rs ...resolver.Builder) DialOption // Experimental
func WithDefaultCallOptions(cos ...CallOption) DialOption
// Interceptors
func WithUnaryInterceptor(f UnaryClientInterceptor) DialOption
func WithStreamInterceptor(f StreamClientInterceptor) DialOption
func WithChainUnaryInterceptor(interceptors ...UnaryClientInterceptor) DialOption
func WithChainStreamInterceptor(interceptors ...StreamClientInterceptor) DialOption
// Stats and observability
func WithStatsHandler(h stats.Handler) DialOption
func WithChannelzParentID(c channelz.Identifier) DialOption // Experimental
// Message size limits
func WithMaxMsgSize(s int) DialOption // Deprecated: use WithDefaultCallOptions(MaxCallRecvMsgSize(s))
func WithDefaultCallOptions(cos ...CallOption) DialOption
// Use with MaxCallRecvMsgSize(bytes int) and MaxCallSendMsgSize(bytes int)
// Header sizes
func WithMaxHeaderListSize(s uint32) DialOption
// Window sizes and flow control
func WithInitialWindowSize(s int32) DialOption
func WithInitialConnWindowSize(s int32) DialOption
func WithStaticStreamWindowSize(s int32) DialOption
func WithStaticConnWindowSize(s int32) DialOption
// Buffer sizes
func WithReadBufferSize(s int) DialOption
func WithWriteBufferSize(s int) DialOption
func WithSharedWriteBuffer(val bool) DialOption // Experimental
// Keepalive
func WithKeepaliveParams(kp keepalive.ClientParameters) DialOption
// Dialer customization
func WithContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption
func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption // Deprecated
// Proxy configuration
func WithNoProxy() DialOption // Experimental
func WithLocalDNSResolution() DialOption // Experimental
// Retry and error handling
func WithDisableRetry() DialOption
func WithMaxCallAttempts(n int) DialOption
func WithDisableHealthCheck() DialOption // Experimental
func FailOnNonTempDialError(f bool) DialOption // Deprecated
func WithReturnConnectionError() DialOption // Deprecated
// Codec (deprecated - use encoding package)
func WithCodec(c Codec) DialOption // Deprecated
func WithCompressor(cp Compressor) DialOption // Deprecated
func WithDecompressor(dc Decompressor) DialOption // Deprecated
// User agent
func WithUserAgent(s string) DialOptiontype ConnectParams struct {
// Backoff specifies the configuration options for connection backoff
Backoff backoff.Config
// MinConnectTimeout is the minimum amount of time we are willing to give a connection to complete
MinConnectTimeout time.Duration
}Example:
import "google.golang.org/grpc/backoff"
conn, err := grpc.NewClient("localhost:50051",
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithConnectParams(grpc.ConnectParams{
Backoff: backoff.Config{
BaseDelay: 1.0 * time.Second,
Multiplier: 1.6,
Jitter: 0.2,
MaxDelay: 120 * time.Second,
},
MinConnectTimeout: 5 * time.Second,
}))type BackoffConfig struct {
MaxDelay time.Duration
}
var DefaultBackoffConfig = BackoffConfig{
MaxDelay: 120 * time.Second,
}type EmptyDialOption struct{}Embeddable type for creating custom dial options.
type Server struct {
// Has unexported fields
}// NewServer creates a gRPC server with the specified options
func NewServer(opt ...ServerOption) *ServerExample:
import (
"net"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// Basic server
s := grpc.NewServer()
// With TLS
creds, _ := credentials.NewServerTLSFromFile("server.crt", "server.key")
s := grpc.NewServer(grpc.Creds(creds))
// With multiple options
s := grpc.NewServer(
grpc.Creds(creds),
grpc.MaxConcurrentStreams(100),
grpc.KeepaliveParams(keepalive.ServerParameters{
MaxConnectionIdle: 5 * time.Minute,
Time: 10 * time.Second,
Timeout: 3 * time.Second,
}),
grpc.ChainUnaryInterceptor(loggingInterceptor, authInterceptor),
grpc.ChainStreamInterceptor(streamLoggingInterceptor),
)// RegisterService registers a service and its implementation
func (s *Server) RegisterService(sd *ServiceDesc, ss any)
// Serve accepts incoming connections on the listener
func (s *Server) Serve(lis net.Listener) error
// ServeHTTP implements http.Handler for HTTP/2 multiplexing (experimental)
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
// GracefulStop gracefully stops the server
func (s *Server) GracefulStop()
// Stop immediately stops the server
func (s *Server) Stop()
// GetServiceInfo returns service information for all registered services
func (s *Server) GetServiceInfo() map[string]ServiceInfoExample:
// Start server
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
// Start serving
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
// Graceful shutdown
go func() {
<-ctx.Done()
s.GracefulStop()
}()Server options configure server behavior.
type ServerOption interface {
// Has unexported methods
}
// Credentials
func Creds(c credentials.TransportCredentials) ServerOption
// Interceptors
func UnaryInterceptor(i UnaryServerInterceptor) ServerOption
func StreamInterceptor(i StreamServerInterceptor) ServerOption
func ChainUnaryInterceptor(interceptors ...UnaryServerInterceptor) ServerOption
func ChainStreamInterceptor(interceptors ...StreamServerInterceptor) ServerOption
// Message size limits
func MaxMsgSize(m int) ServerOption // Deprecated: use MaxRecvMsgSize
func MaxRecvMsgSize(m int) ServerOption
func MaxSendMsgSize(m int) ServerOption
// Header sizes
func MaxHeaderListSize(s uint32) ServerOption
func HeaderTableSize(s uint32) ServerOption // Experimental
// Connection limits
func MaxConcurrentStreams(n uint32) ServerOption
// Connection timeout
func ConnectionTimeout(d time.Duration) ServerOption
// Keepalive
func KeepaliveParams(kp keepalive.ServerParameters) ServerOption
func KeepaliveEnforcementPolicy(kep keepalive.EnforcementPolicy) ServerOption
// Window sizes and flow control
func InitialWindowSize(s int32) ServerOption
func InitialConnWindowSize(s int32) ServerOption
func StaticStreamWindowSize(s int32) ServerOption
func StaticConnWindowSize(s int32) ServerOption
// Buffer sizes
func ReadBufferSize(s int) ServerOption
func WriteBufferSize(s int) ServerOption
func SharedWriteBuffer(val bool) ServerOption // Experimental
// Worker configuration
func NumStreamWorkers(numServerWorkers uint32) ServerOption // Experimental
// Stats and observability
func StatsHandler(h stats.Handler) ServerOption
func InTapHandle(h tap.ServerInHandle) ServerOption // Experimental
// Unknown service handler
func UnknownServiceHandler(streamHandler StreamHandler) ServerOption
// Shutdown behavior
func WaitForHandlers(w bool) ServerOption // Experimental
// Codec (deprecated - use encoding package)
func CustomCodec(codec Codec) ServerOption // Deprecated
func ForceServerCodec(codec encoding.Codec) ServerOption // Deprecated
func ForceServerCodecV2(codecV2 encoding.CodecV2) ServerOption // Experimental
// Compression (deprecated - use encoding package)
func RPCCompressor(cp Compressor) ServerOption // Deprecated
func RPCDecompressor(dc Decompressor) ServerOption // Deprecatedtype EmptyServerOption struct{}Embeddable type for creating custom server options.
type ServiceDesc struct {
ServiceName string
// The pointer to the service interface
HandlerType any
Methods []MethodDesc
Streams []StreamDesc
Metadata any
}type MethodDesc struct {
MethodName string
Handler MethodHandler
}
type MethodHandler func(srv any, ctx context.Context, dec func(any) error, interceptor UnaryServerInterceptor) (any, error)type ServiceInfo struct {
Methods []MethodInfo
Metadata any
}
type MethodInfo struct {
Name string
IsClientStream bool
IsServerStream bool
}type ServiceRegistrar interface {
RegisterService(desc *ServiceDesc, impl any)
}This interface allows service registration with types other than *grpc.Server.
Call options configure individual RPC calls.
type CallOption interface {
// Has unexported methods
}
// Metadata
func Header(md *metadata.MD) CallOption
func Trailer(md *metadata.MD) CallOption
// Peer information
func Peer(p *peer.Peer) CallOption
// Credentials
func PerRPCCredentials(creds credentials.PerRPCCredentials) CallOption
// Message size
func MaxCallRecvMsgSize(bytes int) CallOption
func MaxCallSendMsgSize(bytes int) CallOption
// Retry
func MaxRetryRPCBufferSize(bytes int) CallOption // Experimental
func WaitForReady(waitForReady bool) CallOption
func FailFast(failFast bool) CallOption // Deprecated: use WaitForReady
// Codec and compression
func ForceCodec(codec encoding.Codec) CallOption // Experimental
func ForceCodecV2(codec encoding.CodecV2) CallOption // Experimental
func CallContentSubtype(contentSubtype string) CallOption
func UseCompressor(name string) CallOption // Experimental
func CallCustomCodec(codec Codec) CallOption // Deprecated
// Authority
func CallAuthority(authority string) CallOption // Experimental
// Callbacks
func OnFinish(onFinish func(err error)) CallOption // Experimental
// Static method marker
func StaticMethod() CallOptionFor advanced use, these struct types expose call option internals:
type HeaderCallOption struct {
HeaderAddr *metadata.MD
}
type TrailerCallOption struct {
TrailerAddr *metadata.MD
}
type PeerCallOption struct {
PeerAddr *peer.Peer
}
type PerRPCCredsCallOption struct {
Creds credentials.PerRPCCredentials
}
type MaxRecvMsgSizeCallOption struct {
MaxRecvMsgSize int
}
type MaxSendMsgSizeCallOption struct {
MaxSendMsgSize int
}
type MaxRetryRPCBufferSizeCallOption struct {
MaxRetryRPCBufferSize int
}
type CompressorCallOption struct {
CompressorType string
}
type ContentSubtypeCallOption struct {
ContentSubtype string
}
type ForceCodecCallOption struct {
Codec encoding.Codec
}
type ForceCodecV2CallOption struct {
CodecV2 encoding.CodecV2
}
type CustomCodecCallOption struct {
Codec Codec
}
type FailFastCallOption struct {
FailFast bool
}
type OnFinishCallOption struct {
OnFinish func(error)
}
type AuthorityOverrideCallOption struct {
Authority string
}
type StaticMethodCallOption struct {
EmptyCallOption
}
type EmptyCallOption struct{}// From google.golang.org/grpc/connectivity package
type State int
const (
Idle State = iota
Connecting
Ready
TransientFailure
Shutdown
)
func (s State) String() stringExample:
import "google.golang.org/grpc/connectivity"
state := conn.GetState()
if state == connectivity.Ready {
log.Println("Connection is ready")
}
// Wait for state change
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if conn.WaitForStateChange(ctx, connectivity.Connecting) {
log.Println("State changed from Connecting")
}// Create a new client stream (wrapper for ClientConn.NewStream)
func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error)
// Invoke a unary RPC (deprecated - use ClientConn.Invoke)
func Invoke(ctx context.Context, method string, args, reply any, cc *ClientConn, opts ...CallOption) errorPreparedMsg is a type for optimizing message encoding when sending the same message multiple times. It pre-encodes a message so it can be efficiently sent to multiple RPCs without re-encoding.
type PreparedMsg struct {
// Has unexported fields
}
// Encode marshals and compresses the message using the codec and compressor for the given stream
func (p *PreparedMsg) Encode(s Stream, msg any) errorUse Case: When broadcasting the same message to multiple clients or streams, encoding once and reusing improves performance.
Example:
import "google.golang.org/grpc"
// Prepare a message for efficient reuse
var preparedMsg grpc.PreparedMsg
err := preparedMsg.Encode(stream, message)
if err != nil {
log.Fatalf("failed to encode: %v", err)
}
// Send to multiple streams efficiently
// The encoded message is reused internallyconst Version = "1.77.0"
// Support package version constants
const (
SupportPackageIsVersion3 = true
SupportPackageIsVersion4 = true
SupportPackageIsVersion5 = true
SupportPackageIsVersion6 = true
SupportPackageIsVersion7 = true
SupportPackageIsVersion8 = true
SupportPackageIsVersion9 = true
)var ErrServerStopped = errors.New("grpc: the server has been stopped")
var ErrClientConnClosing = status.Error(codes.Canceled, "grpc: the client connection is closing") // Deprecated
var ErrClientConnTimeout = errors.New("grpc: timed out when dialing") // DeprecatedgRPC-Go uses URI syntax for specifying targets:
scheme://[authority]/endpointExamples:
dns:///example.com:443 - DNS resolutiondns://8.8.8.8/example.com:443 - DNS resolution with custom serverunix:///path/to/socket - Unix domain socketpassthrough:///localhost:50051 - Direct connection without name resolutionxds:///myservice - xDS-based service discoveryThe default resolver is dns (can be changed via resolver.SetDefaultScheme).
ClientConn per target and reuse it for multiple RPCsdefer conn.Close() to ensure cleanupGracefulStop() to allow in-flight RPCs to completeMaxConcurrentStreams and message size limitsServe()Example - Complete Server with Graceful Shutdown:
package main
import (
"context"
"log"
"net"
"os"
"os/signal"
"syscall"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
)
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer(
grpc.MaxConcurrentStreams(100),
grpc.KeepaliveParams(keepalive.ServerParameters{
MaxConnectionIdle: 5 * time.Minute,
Time: 10 * time.Second,
Timeout: 3 * time.Second,
}),
grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{
MinTime: 5 * time.Second,
PermitWithoutStream: true,
}),
)
// Register services
// pb.RegisterYourServiceServer(s, &yourService{})
// Handle graceful shutdown
go func() {
sigint := make(chan os.Signal, 1)
signal.Notify(sigint, os.Interrupt, syscall.SIGTERM)
<-sigint
log.Println("Shutting down server...")
s.GracefulStop()
}()
log.Println("Server listening on :50051")
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}