How to Supercharge Go Microservices: Replace HTTP/JSON with gRPC Using easyms.golang

This article walks through a complete performance upgrade of a Go microservice by defining protobuf contracts, generating gRPC code, running both HTTP and gRPC servers side‑by‑side, and using gRPC‑Gateway to keep REST compatibility, resulting in lower latency and a future‑ready architecture.

Code Wrench
Code Wrench
Code Wrench
How to Supercharge Go Microservices: Replace HTTP/JSON with gRPC Using easyms.golang

The original easyms.golang project used an API gateway that called the authentication service (auth‑svc) via HTTP/JSON, which became a performance hotspot as token verification scaled.

Step 1 – Define the protobuf contract

A auth.proto file is created under api/proto/auth describing the VerifyToken RPC, its request and response messages, and the service definition.

syntax = "proto3";

package auth;
option go_package = "easyms.golang/api/proto/auth";

message VerifyRequest {
    string token = 1;
}

message VerifyResponse {
    bool valid = 1;
    // ... additional user info
}

service AuthService {
    rpc VerifyToken(VerifyRequest) returns (VerifyResponse);
}

Step 2 – Generate Go code from the .proto file

The protobuf compiler is invoked to produce Go structs and gRPC stubs:

protoc --proto_path=. \
      --go_out=. --go_opt=paths=source_relative \
      --go-grpc_out=. --go-grpc_opt=paths=source_relative \
      api/proto/auth/auth.proto

On Windows, the required protoc binary can be downloaded from https://github.com/protocolbuffers/protobuf/releases/ and placed in the Go module cache. The command then includes additional include paths:

protoc -I . \
      -I third_party/googleapis \
      -I "D:/app/go/include" \
      --go_out . --go_opt paths=source_relative \
      --go-grpc_out . --go-grpc_opt paths=source_relative \
      api/proto/auth/auth.proto

Step 3 – Implement the gRPC server

A new file grpc_server.go implements the generated AuthServiceServer interface while reusing the existing TokenService business logic.

package service

import (
    pb "easyms.golang/api/proto/auth"
    // ... other imports
)

type grpcServer struct {
    pb.UnimplementedAuthServiceServer
    tokenService TokenService // reuse existing logic
}

func (s *grpcServer) VerifyToken(ctx context.Context, req *pb.VerifyRequest) (*pb.VerifyResponse, error) {
    _, err := s.tokenService.GetOAuth2DetailsByAccessToken(req.Token)
    if err != nil {
        return &pb.VerifyResponse{Valid: false}, nil
    }
    return &pb.VerifyResponse{Valid: true}, nil
}

Step 4 – Run both HTTP and gRPC servers

The service’s main.go is modified to start the gRPC server in a separate goroutine while the original Gin HTTP server continues to run in the main goroutine.

func main() {
    // ... existing DI setup

    // Start gRPC server (goroutine)
    go func() {
        grpcPort := appConfig.Server.Port + 10000 // gRPC port
        lis, err := net.Listen("tcp", fmt.Sprintf(":%d", grpcPort))
        // error handling omitted for brevity
        s := grpc.NewServer()
        pb.RegisterAuthServiceServer(s, service.NewGrpcServer(...))
        s.Serve(lis)
    }()

    // Start HTTP server (main goroutine)
    g := gin.Default()
    // ... route registration
    g.Run(...)
}

Step 5 – Upgrade the API gateway to use gRPC

A gRPC client is created in gateway.go (via grpc.Dial) and the existing HTTP call to auth‑svc is replaced with a gRPC call inside AuthMiddleware:

func (g *Gateway) AuthMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // token extraction omitted
        if _, found := g.authCache.Get(tokenStr); found {
            next.ServeHTTP(w, r)
            return
        }
        // gRPC verification
        resp, err := g.authSvcClient.VerifyToken(r.Context(), &pb.VerifyRequest{Token: tokenStr})
        if err != nil || !resp.Valid {
            // error handling
            return
        }
        g.authCache.Set(tokenStr, true, 5*time.Minute)
        next.ServeHTTP(w, r)
    })
}

Step 6 – Expose a RESTful endpoint with gRPC‑Gateway

By adding google.api.http annotations to the .proto file and running the grpc‑gateway plugin, an HTTP POST endpoint /v1/auth/token is automatically mapped to the gRPC method.

import "google/api/annotations.proto";

service AuthService {
    rpc GrantToken(TokenRequest) returns (TokenResponse) {
        option (google.api.http) = {
            post: "/v1/auth/token"
            body: "*"
        };
    }
}

The generated gateway handler is mounted on the Gin router, giving the service both a modern gRPC API and a backward‑compatible REST API that share the same business logic.

Result

Performance boost : Core token verification now uses gRPC/Protobuf, reducing latency and CPU overhead.

Unified contract : Protobuf becomes the single source of truth for service interfaces.

Backward compatibility : Existing HTTP clients continue to work unchanged.

Gradual migration : The pattern can be applied service‑by‑service without a full rewrite.

Source code for the complete implementation is available at:

GitHub: https://github.com/louis-xie-programmer/easyms.golang

Gitee: https://gitee.com/louis_xie/easyms.golang

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.

BackendGogRPCProtobuf
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.