gRPC Quickstart using Golang
What is gRPC?
gRPC is a modern open source high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It is also applicable in last mile of distributed computing to connect devices, mobile applications and browsers to backend services.
source: grpc.io
Prerequisites
Golang plugins for protocol compilers
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
Make sure the GOPATH/bin
is part of your PATH env
export PATH="$PATH:$(go env GOPATH)/bin"
Now, we are ready to get started.
Steps
Setup Projects
Create gRPC server
- Generate proto spec file
Create gRPC client
Test RPCs
Setup Projects
To keep things simple, lets create two projects
Server
Client
Add simple main.go
files in each and initialize go module (ex - go mod init github.com/mridulganga/server
), also make sure to add them in GOPATH as client would need to import a file exposed by the server.
Create gRPC server
Generate proto spec file
Create a new file called helloworld.proto in server project's pkg/helloworld
folder
syntax = "proto3";
option go_package = "github.com/mridulganga/server/pkg/helloworld";
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
Now cd to the folder and run the following command to generate the protobuf and gRPC interface
cd server/pkg/helloworld
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
helloworld.proto
The above step should generate two files in the same folder
helloworld.pb.go
helloworld_grpc.pb.go
Create the server in main.go (server/main.go
)
package main
import (
"context"
"flag"
"fmt"
"log"
"net"
"google.golang.org/grpc"
pb "github.com/mridulganga/server/pkg/helloworld"
)
var (
port = flag.Int("port", 50051, "The server port")
)
// server is used to implement helloworld.GreeterServer.
type server struct {
pb.UnimplementedGreeterServer
}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Printf("Received: %v", in.GetName())
return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}
func main() {
flag.Parse()
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
log.Printf("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
Code taken from https://github.com/grpc/grpc-go/blob/master/examples/helloworld/greeter_server/main.go
Create gRPC client
Create the client in main.go (client/main.go
)
package main
import (
"context"
"flag"
"log"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
pb "github.com/mridulganga/server/pkg/helloworld"
)
const (
defaultName = "world"
)
var (
addr = flag.String("addr", "localhost:50051", "the address to connect to")
name = flag.String("name", defaultName, "Name to greet")
)
func main() {
flag.Parse()
// Set up a connection to the server.
conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn)
// Contact the server and print out its response.
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.GetMessage())
}
code taken from https://github.com/grpc/grpc-go/blob/master/examples/helloworld/greeter_client/main.go
Test RPC
Run the server
go run server/main.go &
Note that we are using & to run server in background, alternatively you can open a new terminal for running the client
Run the client
go run client/main.go
go run client/main.go -name mridul
The client should log "Greeting world" or the name which is supplied. The client is using gRPC to connect to the server and call SayHello method on the server.