What it is
The official Go implementation of gRPC — typed RPC over HTTP/2 with generated clients and servers, streaming in both directions, deadlines and interceptors.
Define services in .proto files, generate Go stubs, then implement the server interface. Interceptors provide the middleware layer for auth, logging and metrics.
Installation
go get google.golang.org/grpcGetting started
The smallest useful thing you can do with it, and what each part means.
go
type server struct {
pb.UnimplementedBookServiceServer // forward compatibility
}
func (s *server) GetBook(ctx context.Context, req *pb.GetBookRequest) (*pb.Book, error) {
book, err := store.Find(ctx, req.GetId())
if errors.Is(err, ErrNotFound) {
return nil, status.Errorf(codes.NotFound, "book %s", req.GetId())
}
return &pb.Book{Id: book.ID, Title: book.Title}, nil
}
// Client
conn, err := grpc.NewClient("localhost:50051",
grpc.WithTransportCredentials(insecure.NewCredentials()))
defer conn.Close()
client := pb.NewBookServiceClient(conn)
book, err := client.GetBook(ctx, &pb.GetBookRequest{Id: "42"})Advanced usage
Where the library earns its place over a simpler alternative.
go
func authInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler) (any, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok || len(md.Get("authorization")) == 0 {
return nil, status.Error(codes.Unauthenticated, "missing token")
}
start := time.Now()
resp, err := handler(ctx, req)
slog.Info("rpc", "method", info.FullMethod,
"code", status.Code(err), "took", time.Since(start))
return resp, err
}
s := grpc.NewServer(grpc.UnaryInterceptor(authInterceptor))Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- rpc error: code = Unknown
- The server returned a plain Go error. Wrap it with status.Errorf and an appropriate code from the codes package.
- context deadline exceeded
- The call outlived its deadline. Either raise it, or check whether the server is blocking on a slow dependency.
Best practices
- Always embed the Unimplemented server struct so proto changes stay backward compatible.
- Return status.Error with a meaningful code; clients switch on codes, not message strings.
- Set deadlines on every client call — an unbounded RPC will eventually hang a caller.
- Reuse one ClientConn; it multiplexes over HTTP/2 and is safe for concurrent use.
Background
Why it exists, and what it was reacting to.
gRPC-Go is the reference implementation from Google and the backbone of most Go microservice communication, including much of Kubernetes' internals.
