gRPC server app using Go

TL;DR

The source code is available in https://github.com/rinoymjoseph/learning-go

Create a directory

mkdir grpc-demo

Initialize a go project named ‘grpc-demo’

 go mod init rinoymjoseph.github.com/grpc-demo

Create a directory to place proto file

mkdir calc
syntax= "proto3";
option go_package= "rinoymjoseph.github.com/grpc-demo/calc";

service calc {
    rpc Add(AddRequest) returns (AddResponse);
}

message AddRequest {
    int32 num1 = 1;
    int32 num2 = 2;
}

message AddResponse {
    int64 sum = 1;
}

Install protoc-gen-go and protoc-gen-go-grpc. Add GOPATH/bin to path

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
export PATH="$PATH:$(go env GOPATH)/bin"

 Generate the gRPC stubs that can be used to implement the service and consume from clients

protoc --go_out=calc \
    --go_opt=paths=source_relative \
    --go-grpc_out=calc \
    --go-grpc_opt=paths=source_relative \
    calc/calc.proto 

This creates two files in calc folder. calc_grpc.pb.go and calc.pb.go.

Add the main.go file

package main

import (
	"context"
	"log"
	"net"

	"google.golang.org/grpc"
	"rinoymjoseph.github.com/grpc-demo/calc"
)

type calcServer struct {
	calc.UnimplementedCalcServer
}

func (s calcServer) Add(ctx context.Context, req *calc.AddRequest) (*calc.AddResponse, error) {
	return &calc.AddResponse{
		Sum: int64(req.Num1 + req.Num2),
	}, nil
}

func main() {
	lis, err := net.Listen("tcp", ":8090")
	if err != nil {
		log.Fatalf("cannot create listener: %s", err)
	}
	serverRegistrar := grpc.NewServer()
	service := &calcServer{}

	calc.RegisterCalcServer(serverRegistrar, service)
	err = serverRegistrar.Serve(lis)
	if err != nil {
		log.Fatalf("impossible to serve: %s", err)
	}
}

The project structure

gRPC Demo Project Structure

Get the packages

go get .
go mod tidy

Run the gRPC server

go run main.go

Postman can be used for testing the gRPC methods

Postman gRPC Test