{
  "slug": "Step-by-Step-Guide-to-Adding-gRPC-to-go-simple----628bc37143b7",
  "title": "Step-by-Step Guide to Adding gRPC to go-simple 🚀",
  "subtitle": "Define the gRPC API with Protocol Buffers",
  "excerpt": "Define the gRPC API with Protocol Buffers",
  "date": "2025-10-11",
  "tags": [
    "Go",
    "API",
    "gRPC"
  ],
  "readingTime": "2 min",
  "url": "https://medium.com/@mobinshaterian/step-by-step-guide-to-adding-grpc-to-go-simple-628bc37143b7",
  "hero": "https://cdn-images-1.medium.com/max/800/1*DNIBurktr1ZA3Y78VQGkDg.png",
  "content": [
    {
      "type": "heading",
      "level": 2,
      "text": "📦 Define the gRPC API with Protocol Buffers"
    },
    {
      "type": "paragraph",
      "html": "The commit added <code>product.proto</code> in <code>api/proto/product/v1</code>, defining the <code>ProductService</code> with full CRUD support:"
    },
    {
      "type": "code",
      "lang": "protobuf",
      "code": "syntax = \"proto3\";\npackage product.v1;\noption go_package = \"github.com/mobintmu/go-simple/api/proto/product/v1\";\nimport \"google/protobuf/empty.proto\";\n\nmessage ProductRequest {\n int32 id = 1;\n\n}\n\nmessage ProductResponse {\n  int32 id = 1;\n  string name = 2;\n  string description = 3;\n  int64 price = 4;\n\n}\n\nmessage CreateProductRequest {\n string name = 1;\n string description = 2;\n int64 price = 3;\n\n}\n\nmessage UpdateProductRequest {\n int32 id = 1;\n string name = 2;\n string description = 3;\n int64 price = 4;\n\n}\n\nmessage DeleteProductRequest {\n int32 id = 1;\n\n}\n\nmessage ListProductsResponse {\n repeated ProductResponse products = 1;\n\n}\n\nservice ProductService {\n\nrpc GetProductByID(ProductRequest) returns (ProductResponse);\n\nrpc CreateProduct(CreateProductRequest) returns (ProductResponse);\n\nrpc UpdateProduct(UpdateProductRequest) returns (ProductResponse);\n\nrpc DeleteProduct(DeleteProductRequest) returns (ProductResponse);\n\nrpc ListProducts(google.protobuf.Empty) returns (ListProductsResponse);\n\n}"
    },
    {
      "type": "paragraph",
      "html": "This schema was compiled using <code>protoc</code>, generating:"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "<code>product.pb.go</code>",
        "<code>product_grpc.pb.go</code>"
      ]
    },
    {
      "type": "code",
      "lang": "text",
      "code": "protoc -I.   --go_out=. --go_opt=paths=source_relative   --go-grpc_out=.\n--go-grpc_opt=paths=source_relative   --grpc-gateway_out=. --grpc-gateway_opt=paths=source_relative\napi/proto/product/v1/product.proto"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*DNIBurktr1ZA3Y78VQGkDg.png",
      "alt": "Step-by-Step Guide to Adding gRPC to go-simple 🚀",
      "caption": "",
      "width": 1024,
      "height": 1024
    },
    {
      "type": "heading",
      "level": 2,
      "text": "2. 🧠 Implement the gRPC Controller"
    },
    {
      "type": "paragraph",
      "html": "The file <code>internal/product/controller/grpc.go</code> was added to wrap the existing product service logic in gRPC handlers:"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "type ProductGRPC struct {\n    productv1.UnimplementedProductServiceServer svc *service.Product\n}\nfunc NewProductGRPC(svc *service.Product) productv1.ProductServiceServer {\n    return &ProductGRPC{\n        svc: svc\n    }\n}"
    },
    {
      "type": "paragraph",
      "html": "Each RPC method (e.g. <code>GetProductByID</code>, <code>CreateProduct</code>) maps to the corresponding service method, ensuring consistent behavior across HTTP and gRPC."
    },
    {
      "type": "heading",
      "level": 2,
      "text": "3. 🛠️ Setup the gRPC Server with Uber FX"
    },
    {
      "type": "paragraph",
      "html": "The file <code>internal/server/grpc.go</code> defines <code>NewGRPCServer</code>, which registers the gRPC service and starts the server using FX lifecycle hooks:"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func NewGRPCServer(p Params) *grpc.Server {\n    server := grpc.NewServer() productv1.RegisterProductServiceServer(server, p.Product)...\n}"
    },
    {
      "type": "paragraph",
      "html": "This allows the server to start automatically when the app runs."
    },
    {
      "type": "heading",
      "level": 2,
      "text": "4. 🧪 Add gRPC Tests"
    },
    {
      "type": "paragraph",
      "html": "The commit also added <code>test/product_grpc_test.go</code>, which tests the <code>GetProductByID</code> method using a real gRPC client:"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "conn, err := grpc.Dial(\"localhost:9090\",\ngrpc.WithTransportCredentials(insecure.NewCredentials()))client :=\nproductv1.NewProductServiceClient(conn)resp, err := client.GetProductByID(context.Background(),\n&productv1.ProductRequest{Id: 1})"
    },
    {
      "type": "paragraph",
      "html": "This ensures the gRPC server is correctly wired and responds as expected."
    },
    {
      "type": "heading",
      "level": 2,
      "text": "5. 📄 Update Project Configuration"
    },
    {
      "type": "paragraph",
      "html": "The commit updated:"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "<code>go.mod</code> and <code>go.sum</code> to include gRPC and protobuf dependencies",
        "<code>buf.gen.yaml</code> to configure code generation with <code>protoc-gen-go</code> and <code>protoc-gen-go-grpc</code>"
      ]
    },
    {
      "type": "paragraph",
      "html": "Buf.gen.yaml"
    },
    {
      "type": "code",
      "lang": "yaml",
      "code": "version: v2plugins:  - local: protoc-gen-go    out: gen/go    opt:      - paths=source_relative  -\nlocal: protoc-gen-go-grpc    out: gen/go    opt:      - paths=source_relative"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "✅ Summary"
    },
    {
      "type": "paragraph",
      "html": "This commit laid the foundation for gRPC in <code>go-simple</code> by:"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "Defining a complete gRPC API",
        "Implementing controller logic",
        "Wiring the server with Uber FX",
        "Adding integration tests"
      ]
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Github Commit"
    }
  ]
}
