gRPC for Go (Golang): Libraries and Examples
gRPC is a high-performance remote procedure call (RPC) framework from Google, based on HTTP/2 and Protocol Buffers (protobuf). For the Go language, there is an official implementation called grpc-go, which allows you to create efficient microservices with support for bidirectional streaming, TLS encryption, and interceptors. In this article, you will find a complete description of the tools, server and client examples, as well as practical recommendations.
Main Libraries for gRPC in Go
- google.golang.org/grpc — the main gRPC library for Go. Includes server and client parts, support for streams, metadata, and load balancing.
- google.golang.org/protobuf — package for working with protobuf messages: compilation, serialization, deserialization.
- github.com/golang/protobuf/protoc-gen-go — plugin for the
protoccompiler that generates Go code from.protofiles. - github.com/grpc-ecosystem/grpc-gateway — utility for creating a REST proxy over gRPC (useful for browser compatibility).
Installation and Setup
Before starting, install the protobuf compiler and plugins:
# Install protoc (Linux/macOS)sudo apt install protobuf-compiler # Ubuntu/Debianbrew install protobuf # macOS
# Install Go pluginsgo install google.golang.org/protobuf/cmd/protoc-gen-go@latestgo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latestAfter installation, update PATH by adding $GOPATH/bin.
Defining a Service via .proto File
Create a file hello.proto:
syntax = "proto3";
package hello;
option go_package = "example.com/grpc-demo/hello";
service Greeter { rpc SayHello (HelloRequest) returns (HelloReply); rpc SayHelloStream (HelloRequest) returns (stream HelloReply);}
message HelloRequest { string name = 1;}
message HelloReply { string message = 1;}Generate Go code with the command:
protoc --go_out=. --go-grpc_out=. hello.protoFiles hello.pb.go (messages) and hello_grpc.pb.go (service) will appear.
Example Server in Go
package main
import ( "log" "net"
pb "example.com/grpc-demo/hello" "google.golang.org/grpc")
type server struct { pb.UnimplementedGreeterServer}
func (s *server) SayHello(req *pb.HelloRequest, stream pb.Greeter_SayHelloServer) error { // Unary RPC return stream.Send(&pb.HelloReply{Message: "Hello, " + req.Name})}
func (s *server) SayHelloStream(req *pb.HelloRequest, stream pb.Greeter_SayHelloServer) error { // Streaming response for i := 0; i < 5; i++ { if err := stream.Send(&pb.HelloReply{Message: "Hello " + req.Name + " #" + string(rune(i))}); err != nil { return err } } return nil}
func main() { lis, _ := net.Listen("tcp", ":50051") s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{}) log.Println("Server listening on :50051") if err := s.Serve(lis); err != nil { log.Fatalf("Failed to serve: %v", err) }}Example Client in Go
package main
import ( "context" "log" "time"
pb "example.com/grpc-demo/hello" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure")
func main() { conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close()
client := pb.NewGreeterClient(conn) ctx, ca