Lesson 52 of 60 · Go
Building a Microservice with gRPC
Duration: 30 minutes
gRPC Basics
This lesson explains the main concept clearly with beginner-friendly examples and background so you can learn why the code works.
Install protobuf tools:
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
Define a service (proto/todo.proto)
syntax = "proto3";
package todo;
service TodoService {
rpc Create (CreateRequest) returns (CreateResponse);
rpc List (ListRequest) returns (ListResponse);
}
message Todo { int32 id = 1; string title = 2; bool done = 3; }
message CreateRequest { string title = 1; }
message CreateResponse { Todo todo = 1; }
message ListRequest {}
message ListResponse { repeated Todo todos = 1; }
Generate Go code:
$ protoc --go_out=. --go-grpc_out=. proto/todo.proto
Server implementation
type server struct { todo.UnimplementedTodoServiceServer; store map[int32]*todo.Todo; next int32 }
func (s *server) Create(ctx context.Context, req *todo.CreateRequest) (*todo.CreateResponse, error) {
s.next++
t := &todo.Todo{Id: s.next, Title: req.Title, Done: false}
s.store[t.Id] = t
return &todo.CreateResponse{Todo: t}, nil
}
func (s *server) List(ctx context.Context, _ *todo.ListRequest) (*todo.ListResponse, error) {
resp := &todo.ListResponse{}
for _, t := range s.store { resp.Todos = append(resp.Todos, t) }
return resp, nil
}
func main() {
lis, _ := net.Listen("tcp", ":50051")
s := grpc.NewServer()
todo.RegisterTodoServiceServer(s, &server{store: make(map[int32]*todo.Todo)})
log.Fatal(s.Serve(lis))
}
Client stub
conn, _ := grpc.Dial("localhost:50051", grpc.WithInsecure())
client := todo.NewTodoServiceClient(conn)
resp, _ := client.Create(context.Background(), &todo.CreateRequest{Title: "Buy milk"})
fmt.Println(resp.Todo)