samber/cc-skills-golang

golang-grpc

Provides gRPC usage guidelines, protobuf organization, and production-ready patterns for Golang microservices.

All-time #647 Trending #1745 First seen Mar 22, 2026
8-week activity · all time api

Installation

$ npx skills add samber/cc-skills-golang --skill golang-grpc

Summary

  • Provides gRPC usage guidelines, protobuf organization, and production-ready patterns for Golang microservices.
  • Use when implementing, reviewing, or debugging gRPC servers/clients, writing proto files, setting up interceptors, handling gRPC errors with status codes, configuring TLS/mTLS, testing with bufconn, or working with streaming RPCs.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Security audits

Partner security reviews for this skill.

agent-trust-hub SAFE

Analyzed Apr 8, 2026

This skill provides safe and standard best practices for implementing gRPC services in Go. It includes guidelines for service definition, error handling, testing, and security. No malicious patterns or vulnerabilities were detected.

snyk LOW

Analyzed Apr 8, 2026

No issues detected.

socket Score 0.9000 · 0 alerts

Analyzed Apr 8, 2026

  • license 1
  • maintenance 1
  • quality 0.9
  • supply chain 1
  • vulnerability 1

0 alerts

Also in this package

Other skills from samber/cc-skills-golang · top by installs.

npx skills add samber/cc-skills-golang

Browse all from samber/cc-skills-golang

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Declared
Cursor Not declared
Codex Declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 3.2K
License LICENSE
Default branch main
Open issues 3
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.2.2
LicenseMIT
CompatibilityDesigned for Claude Code, Codex or similar harness, and for projects using Golang.
Allowed toolsRead Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent WebFetch mcp__context7__resolve-library-id mcp__context7__query-docs Bash(protoc:*) AskUserQuestion Bash(godig:*) Bash(gopls:*) LSP mcp__gopls__*
Declared agents claude-code codex clawdbot
More metadata
author
samber
version
1.2.2
openclaw
{"emoji":"🌐","homepage":"https:\/\/github.com\/samber\/cc-skills-golang","requires":{"bins":["go","protoc"]},"install":{"0":"kind: brew","formula":"protobuf","bins":["protoc"]}}

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 10,143 B
  • docs SUMMARY.md 360 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 36,800 installs

SKILL.md

Persona: You are a Go distributed systems engineer. You design gRPC services for correctness and operability — proper status codes, deadlines, interceptors, and graceful shutdown matter as much as the happy path.

Modes:

  • Build mode — implementing a new gRPC server or client from scratch.
  • Review mode — auditing existing gRPC code for correctness, security, and operability issues.

Dependencies:

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

Go gRPC Best Practices

Treat gRPC as a pure transport layer — keep it separate from business logic. The official Go implementation is google.golang.org/grpc.

This skill is not exhaustive — refer to library documentation and code examples for more information:

  • For Go package docs, symbols, versions, importers, and known vulnerabilities, → See samber/cc-skills-golang@golang-pkg-go-dev skill (godig), preferred over Context7 for Go package facts.
  • To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See samber/cc-skills-golang@golang-gopls skill (gopls).
  • Context7 remains a fallback for docs not indexed on pkg.go.dev.

Quick Reference

Concern Package / Tool
Service definition protoc or buf with .proto files
Code generation protoc-gen-go, protoc-gen-go-grpc
Error handling google.golang.org/grpc/status with codes
Rich error details google.golang.org/genproto/googleapis/rpc/errdetails
Interceptors grpc.ChainUnaryInterceptor, grpc.ChainStreamInterceptor
Middleware ecosystem github.com/grpc-ecosystem/go-grpc-middleware
Testing google.golang.org/grpc/test/bufconn
TLS / mTLS google.golang.org/grpc/credentials
Health checks google.golang.org/grpc/health

Proto File Organization

Organize by domain with versioned directories (proto/user/v1/). Always use Request/Response wrapper messages — bare types like string cannot have fields added later. Generate with buf generate or protoc.

[Proto & code generation reference](references/protoc-reference.md)

Server Implementation

  • Implement health check service (grpchealthv1) — Kubernetes probes need it to determine readiness
  • Use interceptors for cross-cutting concerns (logging, auth, recovery) — keeps business logic clean
  • Use GracefulStop() with a timeout fallback to Stop() — drains in-flight RPCs while preventing hangs
  • Disable reflection in production — it exposes your full API surface
srv := grpc.NewServer(
    grpc.ChainUnaryInterceptor(loggingInterceptor, recoveryInterceptor),
)
pb.RegisterUserServiceServer(srv, svc)
healthpb.RegisterHealthServer(srv, health.NewServer())

go srv.Serve(lis)

// On shutdown signal:
stopped := make(chan struct{})
go func() { srv.GracefulStop(); close(stopped) }()
select {
case <-stopped:
case <-time.After(15 * time.Second):
    srv.Stop()
}

Interceptor Pattern

func loggingInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
    start := time.Now()
    resp, err := handler(ctx, req)
    log.Printf("method=%s duration=%s code=%s", info.FullMethod, time.Since(start), status.Code(err))
    return resp, err
}

Client Implementation

  • Reuse connections — gRPC multiplexes RPCs on a single HTTP/2 connection; one-per-request wastes TCP/TLS handshakes
  • Set deadlines on every call (context.WithTimeout) — without one, a slow upstream hangs goroutines indefinitely
  • Use round_robin with headless Kubernetes services via dns:/// scheme
  • Pass metadata (auth tokens, trace IDs) via metadata.NewOutgoingContext
conn, err := grpc.NewClient("dns:///user-service:50051",
    grpc.WithTransportCredentials(creds),
    grpc.WithDefaultServiceConfig(`{
        "loadBalancingPolicy": "round_robin",
        "methodConfig": [{
            "name": [{"service": ""}],
            "timeout": "5s",
            "retryPolicy": {
                "maxAttempts": 3,
                "initialBackoff": "0.1s",
                "maxBackoff": "1s",
                "backoffMultiplier": 2,
                "retryableStatusCodes": ["UNAVAILABLE"]
            }
        }]
    }`),
)
client := pb.NewUserServiceClient(conn)

Error Handling

Always return gRPC errors using status.Error with a specific code — a raw error becomes codes.Unknown, telling the client nothing actionable. Clients use codes to decide retry vs fail-fast vs degrade.

Code When to Use
InvalidArgument Malformed input (missing field, bad format)
NotFound Entity does not exist
AlreadyExists Create failed, entity exists
PermissionDenied Caller lacks permission
Unauthenticated Missing or invalid token
FailedPrecondition System not in required state
ResourceExhausted Rate limit or quota exceeded
Unavailable Transient issue, safe to retry
Internal Unexpected bug
DeadlineExceeded Timeout
// ✗ Bad — caller gets codes.Unknown, can't decide whether to retry
return nil, fmt.Errorf("user not found")

// ✓ Good — specific code lets clients act appropriately
if errors.Is(err, ErrNotFound) {
    return nil, status.Errorf(codes.NotFound, "user %q not found", req.UserId)
}
return nil, status.Errorf(codes.Internal, "lookup failed: %v", err)

For field-level validation errors, attach errdetails.BadRequest via status.WithDetails.

Streaming

Pattern Use Case
Server streaming Server sends a sequence (log tailing, result sets)
Client streaming Client sends a sequence, server responds once (file upload, batch)
Bidirectional Both send independently (chat, real-time sync)

Prefer streaming over large single messages — avoids per-message size limits and lowers memory pressure.

func (s *server) ListUsers(req *pb.ListUsersRequest, stream pb.UserService_ListUsersServer) error {
    for _, u := range users {
        if err := stream.Send(u); err != nil {
            return err
        }
    }
    return nil
}

Testing

Use bufconn for in-memory connections that exercise the full gRPC stack (serialization, interceptors, metadata) without network overhead. Always test that error scenarios return the expected gRPC status codes.

[Testing patterns and examples](references/testing.md)

Security

  • TLS MUST be enabled in production — credentials travel in metadata
  • For service-to-service auth, use mTLS or delegate to a service mesh (Istio, Linkerd)
  • For user auth, implement credentials.PerRPCCredentials and validate tokens in an auth interceptor
  • Reflection SHOULD be disabled in production to prevent API discovery

Performance

Setting Purpose Typical Value
keepalive.ServerParameters.Time Ping interval for idle connections 30s
keepalive.ServerParameters.Timeout Ping ack timeout 10s
grpc.MaxRecvMsgSize Override 4 MB default for large payloads 16 MB
Connection pooling Multiple conns for high-load streaming 4 connections

Most services do not need connection pooling — profile before adding complexity.

Common Mistakes

Mistake Fix
Returning raw error Becomes codes.Unknown — client can't decide whether to retry. Use status.Errorf with a specific code
No deadline on client calls Slow upstream hangs indefinitely. Always context.WithTimeout
New connection per request Wastes TCP/TLS handshakes. Create once, reuse — HTTP/2 multiplexes RPCs
Reflection enabled in production Lets attackers enumerate every method. Enable only in dev/staging
codes.Internal for all errors Wrong codes break client retry logic. Unavailable triggers retry; InvalidArgument does not
Bare types as RPC arguments Can't add fields to string. Wrapper messages allow backwards-compatible evolution
Missing health check service Kubernetes can't determine readiness, kills pods during deployments
Ignoring context cancellation Long operations continue after caller gave up. Check ctx.Err()

Cross-References

  • → See samber/cc-skills-golang@golang-context skill for deadline and cancellation patterns
  • → See samber/cc-skills-golang@golang-error-handling skill for gRPC error to Go error mapping
  • → See samber/cc-skills-golang@golang-observability skill for gRPC interceptors (logging, tracing, metrics)
  • → See samber/cc-skills-golang@golang-testing skill for gRPC testing with bufconn