skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
bobmatnyc/claude-mpm-skills499 installs

golang-grpc

Production gRPC in Go: protobuf layout, codegen, interceptors, deadlines, error codes, streaming, health checks, TLS, and testing with bufconn

How do I install this agent skill?

npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill golang-grpc
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    This skill provides a standard technical guide for building gRPC services in Go. It includes instructions for setting up Protocol Buffers, implementing servers, and following production best practices such as TLS, health checks, and error handling. No security issues were detected.

  • Socketpass

    No alerts

  • Snykpass

    Risk: LOW · No issues

  • Runlayerwarn

    2/2 files flagged

What does this agent skill do?

Go gRPC (Production)

Overview

gRPC provides strongly-typed RPC APIs backed by Protocol Buffers, with first-class streaming support and excellent performance for service-to-service communication. This skill focuses on production defaults: versioned protos, deadlines, error codes, interceptors, health checks, TLS, and testability.

Quick Start

1) Define a versioned protobuf API

✅ Correct: versioned package

// proto/users/v1/users.proto
syntax = "proto3";

package users.v1;
option go_package = "example.com/myapp/gen/users/v1;usersv1";

service UsersService {
  rpc GetUser(GetUserRequest) returns (GetUserResponse);
  rpc ListUsers(ListUsersRequest) returns (stream User);
}

message GetUserRequest { string id = 1; }
message GetUserResponse { User user = 1; }
message ListUsersRequest { int32 page_size = 1; string page_token = 2; }

message User {
  string id = 1;
  string email = 2;
  string display_name = 3;
}

❌ Wrong: unversioned package (hard to evolve)

package users;

2) Generate Go code

Install generators:

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

Generate:

protoc -I proto \
  --go_out=./gen --go_opt=paths=source_relative \
  --go-grpc_out=./gen --go-grpc_opt=paths=source_relative \
  proto/users/v1/users.proto

3) Implement server with deadlines and status codes

✅ Correct: validate + map errors to gRPC codes

package usersvc

import (
    "context"

    "google.golang.org/grpc/codes"
    "google.golang.org/grpc/status"

    usersv1 "example.com/myapp/gen/users/v1"
)

type Service struct {
    usersv1.UnimplementedUsersServiceServer
    Repo Repo
}

type Repo interface {
    GetUser(ctx context.Context, id string) (User, error)
}

type User struct {
    ID, Email, DisplayName string
}

func (s *Service) GetUser(ctx context.Context, req *usersv1.GetUserRequest) (*usersv1.GetUserResponse, error) {
    if req.GetId() == "" {
        return nil, status.Error(codes.InvalidArgument, "id is required")
    }

    u, err := s.Repo.GetUser(ctx, req.GetId())
    if err != nil {
        if err == ErrNotFound {
            return nil, status.Error(codes.NotFound, "user not found")
        }
        return nil, status.Error(codes.Internal, "internal error")
    }

    return &usersv1.GetUserResponse{
        User: &usersv1.User{
            Id:          u.ID,
            Email:       u.Email,
            DisplayName: u.DisplayName,
        },
    }, nil
}

❌ Wrong: return raw errors (clients lose code semantics)

return nil, errors.New("user not found")

Core Concepts

Deadlines and cancellation

Make every call bounded; enforce server-side timeouts for expensive handlers.

✅ Correct: require deadline

if _, ok := ctx.Deadline(); !ok {
    return nil, status.Error(codes.InvalidArgument, "deadline required")
}

Metadata

Use metadata for auth/session correlation, not for primary request data.

✅ Correct: read auth token from metadata

md, _ := metadata.FromIncomingContext(ctx)
auth := ""
if vals := md.Get("authorization"); len(vals) > 0 {
    auth = vals[0]
}

Interceptors (Middleware)

Use interceptors for cross-cutting concerns: auth, logging, metrics, tracing, request IDs.

✅ Correct: unary interceptor with request ID

func unaryRequestID() grpc.UnaryServerInterceptor {
    return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
        id := uuid.NewString()
        ctx = context.WithValue(ctx, requestIDKey{}, id)
        resp, err := handler(ctx, req)
        return resp, err
    }
}

Streaming patterns

Server streaming (paginate or stream results)

✅ Correct: stop on ctx.Done()

func (s *Service) ListUsers(req *usersv1.ListUsersRequest, stream usersv1.UsersService_ListUsersServer) error {
    users, err := s.Repo.ListUsers(stream.Context(), int(req.GetPageSize()))
    if err != nil {
        return status.Error(codes.Internal, "internal error")
    }

    for _, u := range users {
        select {
        case <-stream.Context().Done():
            return stream.Context().Err()
        default:
        }

        if err := stream.Send(&usersv1.User{
            Id:          u.ID,
            Email:       u.Email,
            DisplayName: u.DisplayName,
        }); err != nil {
            return err
        }
    }
    return nil
}

Unary vs streaming decision

  • Use unary for single request/response and simple retries.
  • Use server streaming for large result sets or continuous updates.
  • Use client streaming for bulk uploads with one final response.
  • Use bidirectional streaming for interactive protocols.

Production Hardening

Health checks and reflection

Add health service; enable reflection only in non-production environments.

✅ Correct: health + conditional reflection

hs := health.NewServer()
grpc_health_v1.RegisterHealthServer(s, hs)

if env != "production" {
    reflection.Register(s)
}

Graceful shutdown

Prefer GracefulStop with a deadline.

✅ Correct: graceful stop

stopped := make(chan struct{})
go func() {
    grpcServer.GracefulStop()
    close(stopped)
}()

select {
case <-stopped:
case <-time.After(10 * time.Second):
    grpcServer.Stop()
}

TLS

Use TLS (or mTLS) in production; avoid insecure credentials outside local dev.

✅ Correct: server TLS

creds, err := credentials.NewServerTLSFromFile("server.crt", "server.key")
if err != nil { return err }

grpcServer := grpc.NewServer(grpc.Creds(creds))

Testing (bufconn)

Test gRPC handlers without opening real sockets using bufconn.

✅ Correct: in-memory gRPC test server

const bufSize = 1024 * 1024

lis := bufconn.Listen(bufSize)
srv := grpc.NewServer()
usersv1.RegisterUsersServiceServer(srv, &Service{Repo: repo})

go func() { _ = srv.Serve(lis) }()

ctx := context.Background()
conn, err := grpc.DialContext(
    ctx,
    "bufnet",
    grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) { return lis.Dial() }),
    grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil { t.Fatal(err) }
defer conn.Close()

client := usersv1.NewUsersServiceClient(conn)
resp, err := client.GetUser(ctx, &usersv1.GetUserRequest{Id: "1"})
_ = resp
_ = err

Anti-Patterns

  • Ignore deadlines: unbounded handlers cause tail latency and resource exhaustion.

  • Return string errors: map domain errors to codes.* with status.Error or status.Errorf.

  • Stream without backpressure: stop on ctx.Done() and handle Send errors.

  • Expose reflection in production: treat reflection as a discovery surface.

Troubleshooting

Symptom: clients see UNKNOWN errors

Actions:

  • Return status.Error(codes.X, "...") instead of raw errors.
  • Wrap domain errors into typed errors, then map to gRPC codes.

Symptom: slow/hanging requests

Actions:

  • Require deadlines and propagate ctx to downstream calls.
  • Add server-side timeouts and bounded concurrency in repositories.

Symptom: flaky streaming

Actions:

  • Stop streaming on ctx.Done() and handle stream.Send errors.
  • Avoid buffering entire result sets before sending.

Resources

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/bobmatnyc/claude-mpm-skills/golang-grpc">View golang-grpc on skillZs</a>