Featured image of post Using gRPC

Using gRPC

In gRPC, client applications can directly call methods on server applications located on different machines as if they were local objects, making it easier to create distributed applications and services.

Preface

  • There are many installation tutorials online. Due to updates in gRPC, many commands may become obsolete. This article reflects the current state at the time of writing.
  • If you encounter issues, the best approach is to refer to the official documentation

Installation

  1. First install Go
  2. Install the protoc compiler https://grpc.io/docs/protoc-installation/
    • The protoc compiler is used to compile .proto files containing service and message definitions
    • Download the zip file matching your OS and architecture (e.g., protoc-3.19.4-linux-x86_64.zip for WSL)
    • Extract the downloaded package:
      • unzip protoc-3.19.4-linux-x86_64.zip -d $HOME/.local
    • Add to PATH:
      • vim ~/.bashrc and add:
      • export PATH="$PATH:$HOME/.local/bin"
      • source ~/.bashrc to refresh environment variables
    • Verify with protoc --version
  3. Install Go plugins
    • The protoc compiler requires these plugins to generate Go code:
      • go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
    • gRPC code generator plugin (previously included in protoc-gen-go):
      • go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1

Core Concepts

  • gRPC supports four service method types:
    • Unary RPC: Client sends single request, server returns single response (like normal function call)
    • Server streaming: Client sends request, gets stream to read message sequence
    • Client streaming: Client sends stream of messages, server returns single response
    • Bidirectional streaming: Both sides send message streams independently
  • Use repeated for bounded datasets that can be generated quickly, stream for large/potentially unbounded datasets

Example Implementation

Project Setup

mkdir grpc-demo && cd grpc-demo
go mod init github.com/seth-shi/grpc-demo

Protocol Definitions

pb/goods.proto:

syntax = "proto3";
package pb;
option go_package="github.com/seth-shi/grpc-demo/pb";

service Goods {
    rpc Show(GoodsShowRequest) returns (GoodsData);
}

message GoodsShowRequest { int64 id = 1; }
message GoodsData {
    int64 id = 1;
    string name = 2;
    double amount = 3;
}

pb/order.proto:

syntax = "proto3";
package pb;
option go_package="github.com/seth-shi/grpc-demo/pb";

service Order {
    rpc Index(OrderIndexRequest) returns (OrderIndexResponse);
    rpc Store(OrderStoreRequest) returns (OrderData);
}

message OrderIndexRequest { int64 userId = 1; }
message OrderIndexResponse { repeated OrderData data = 1; }
message OrderStoreRequest {
    int64 goodsId = 1;
    int64 goodsNumber = 2;
    int64 userId = 3;
    double Amount = 4;
    string goodsName = 5;
}
message OrderData {
    int64 no = 1;
    double amount = 2;
    int64 number = 3;
    int64 goodsId = 4;
    string goodsName = 5;
}

Generate Go code:

protoc --go_out=. --go_opt=paths=source_relative \
       --go-grpc_out=. --go-grpc_opt=paths=source_relative \
       pb/*.proto
go mod tidy

Service Implementations

goods/main.go:

package main
// ... goods service implementation ...

order/main.go:

package main
// ... order service implementation ...

API Gateway

api/main.go:

package main
// ... API implementation with Gin ...

Running the System

# Start services in separate terminals
go run goods/main.go
go run order/main.go 
go run api/main.go

Common Errors

  • rpc error: code = Unavailable desc = connection error:
    • Common in WSL environments - try running services directly on host machine
    • Ensure ports are not blocked by firewall
    • Verify service addresses match in client connections

This implementation demonstrates basic gRPC patterns including:

  • Protocol definition with Protobuf
  • Service implementation patterns
  • Client-server communication
  • Error handling basics
  • API gateway pattern