Boost gRPC Development: Auto‑Generate REST APIs with pbgo and Debug with grpcurl

This guide explains how pbgo extends Protobuf to automatically generate lightweight REST handlers for Go gRPC services and shows how to use the pure‑Go tool grpcurl for fast, code‑free debugging, complete with installation steps, command examples, and practical recommendations.

Code Wrench
Code Wrench
Code Wrench
Boost gRPC Development: Auto‑Generate REST APIs with pbgo and Debug with grpcurl

Part 1: pbgo – Auto‑generate REST interfaces from Protobuf

pbgo is a lightweight Go micro‑framework built on Protobuf that can generate REST routes and handler code for gRPC methods, offering a slimmer alternative to grpc‑gateway. It works by using Protobuf extension fields to annotate methods with REST metadata, which the pbgo plugin reads during code generation.

The extension definition looks like this:

extend google.protobuf.MethodOptions {
  HttpRule rest_api = 20180715;
}

message HttpRule {
  string get = 1;
  string put = 2;
  string post = 3;
  string delete = 4;
  string patch = 5;
}

Developers add the REST mapping directly in the .proto file:

service HelloService {
  rpc Hello(String) returns (String) {
    option (pbgo.rest_api) = {
      get: "/hello/:value"
    };
  }
}

During generation the plugin checks for the extension with:

proto.HasExtension(m.Options, pbgo.E_RestApi)
proto.GetExtension(m.Options, pbgo.E_RestApi)

It extracts the HTTP method and path, then produces a handler such as:

func HelloServiceHandler(svc HelloServiceInterface) http.Handler {
    router := httprouter.New()
    router.Handle("GET", "/hello/:value", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
        var req, res String
        req.Value = ps.ByName("value")
        _ = svc.Hello(&req, &res)
        _ = json.NewEncoder(w).Encode(&res)
    })
    return router
}

A minimal server that starts the generated REST service:

type HelloService struct{}

func (p *HelloService) Hello(req *hello_pb.String, res *hello_pb.String) error {
    res.Value = "hello:" + req.GetValue()
    return nil
}

func main() {
    router := hello_pb.HelloServiceHandler(new(HelloService))
    log.Fatal(http.ListenAndServe(":8080", router))
}

Part 2: grpcurl – The ultimate gRPC debugging tool

grpcurl is a pure‑Go command‑line client that requires no C++ build chain, making installation as easy as:

go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

It works with services that expose the reflection API. Enable reflection in a Go server with:

import "google.golang.org/grpc/reflection"

func main() {
    s := grpc.NewServer()
    hello_pb.RegisterHelloServiceServer(s, &HelloService{})
    reflection.Register(s)
    s.Serve(lis)
}

Common grpcurl commands: grpcurl -plaintext localhost:1234 list – list all services.

grpcurl -plaintext localhost:1234 list HelloService.HelloService

– list methods of a service.

grpcurl -plaintext localhost:1234 describe HelloService.HelloService

– show method signatures and streaming info.

grpcurl -plaintext localhost:1234 describe HelloService.String

– display the protobuf message structure.

grpcurl -plaintext -d '{"value":"gopher"}' localhost:1234 HelloService.HelloService/Hello

– invoke a unary method.

grpcurl -plaintext -d @ localhost:1234 HelloService.HelloService/Channel

– invoke a streaming method, feeding JSON lines via stdin.

Example unary call output:

{"value":"hello:gopher"}

Example streaming call input and output:

{"value":"gopher"}
{"value":"wasm"}
{"value":"hello:gopher"}
{"value":"hello:wasm"}

Practical Recommendations

Define all service contracts in .proto files and generate both gRPC and REST code with pbgo for a unified code base.

Use grpcurl locally to test service logic without writing client code or involving front‑end teams.

Expose REST endpoints for public APIs while keeping gRPC for internal service‑to‑service communication, sharing the same business logic.

Reference Links

pbgo project: https://github.com/chai2010/pbgo

grpcurl project: https://github.com/fullstorydev/grpcurl

Protobuf official site: https://protobuf.dev

Go gRPC reflection documentation: https://pkg.go.dev/google.golang.org/grpc/reflection

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DebugginggRPCProtobufrestgrpcurlpbgo
Code Wrench
Written by

Code Wrench

Focuses on code debugging, performance optimization, and real-world engineering, sharing efficient development tips and pitfall guides. We break down technical challenges in a down-to-earth style, helping you craft handy tools so every line of code becomes a problem‑solving weapon. 🔧💻

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.