К основному содержанию
скилл CX Codex

golang-grpc · bobmatnyc — скилл для Claude Code: что делает и как установить

Направляет агента при разработке production-сервисов на Go с gRPC: от версионирования Protobuf и перехватчиков до graceful shutdown и тестов.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add bobmatnyc/claude-mpm-skills --skill golang-grpc -a claude-code
Открыть на GitHub

Что делает golang-grpc

Скилл задаёт правила построения gRPC-микросервисов на Go. Он инструктирует модель использовать версионированные пакеты в .proto, проставлять статус-коды из пакета codes вместо сырых ошибок и контролировать дедлайны через ctx.Deadline(). Для потоковой передачи данных даётся паттерн прерывания стрима по stream.Context().Done().

Внутри собраны готовые шаблоны для промежуточных обработчиков (unary interceptors) с пробросом request ID, проверка работоспособности через grpc_health_v1 и корректная остановка сервера с таймаутом через GracefulStop. Для тестирования логики без реального сетевого сокета применяется bufconn.

Без установленных бинарников protoc-gen-go и protoc-gen-go-grpc сгенерировать серверные заглушки не получится. Серверная рефлексия по правилам скилла должна включаться строго вне продакшена.

Какие задачи решает

  • Сгенерировать Go-код из версионированных .proto-файлов
  • Добавить перехватчики для трассировки и передачи идентификатора запроса
  • Настроить безопасное завершение сервера через GracefulStop с тайм-аутом
  • Написать тесты для хендлеров gRPC в памяти с помощью bufconn

Примеры запросов агенту

  • Сгенерируй серверный код для proto/users/v1/users.proto с валидацией обязательных полей
  • Добавь унарный интерцептор для генерации request ID и пробрось его в контекст
  • Напиши юнит-тест для GetUser через in-memory листнер bufconn

Как установить golang-grpc

1Через Skills CLI (Vercel)

npx skills add bobmatnyc/claude-mpm-skills --skill golang-grpc -a claude-code

2Вручную: положить файлы

~/.claude/skills/golang-grpc/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/golang-grpc/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о golang-grpc

Как установить golang-grpc в Claude Code?

Запустите команду npx skills add bobmatnyc/claude-mpm-skills --skill golang-grpc -a claude-code. Также можно вручную сохранить файл скилла по пути ~/.claude/skills/golang-grpc/SKILL.md.

Что делает скилл golang-grpc?

Он задаёт инженерные стандарты gRPC для Go: структуру Protobuf, обработку ошибок через gRPC status codes, стриминг, TLS и graceful shutdown.

Как скилл рекомендует тестировать хендлеры?

Скилл предлагает использовать пакет bufconn, чтобы поднимать тестовый gRPC-сервер в оперативной памяти без открытия реальных TCP-портов.

Исходный текст

SKILL.md · MIT
---
name: golang-grpc
description: "Production gRPC in Go: protobuf layout, codegen, interceptors, deadlines, error codes, streaming, health checks, TLS, and testing with bufconn"
user-invocable: false
disable-model-invocation: true
version: 1.0.0
category: toolchain
author: Claude MPM Team
license: MIT
progressive_disclosure:
  entry_point:
    summary: "Build production gRPC services in Go with protobuf-first APIs, interceptors, deadlines, status codes, and streaming patterns"
    when_to_use: "When building Go microservices that need typed RPC, streaming, low latency, or strong client/server contracts with protobuf"
    quick_start: "1. Define versioned protos (pkg v1) 2. Generate Go code 3. Implement server + interceptors 4. Enforce deadlines 5. Test with bufconn"
  token_estimate:
    entry: 160
    full: 6500
context_limit: 900
tags:
  - golang
  - grpc
  - protobuf
  - microservices
  - streaming
  - interceptors
  - observability
requires_tools: []
---

# 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
// 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)**
```proto
package users;
```

### 2) Generate Go code

Install generators:
```bash
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
```

Generate:
```bash
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**
```go
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)**
```go
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**
```go
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**
```go
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**
```go
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()**
```go
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**
```go
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**
```go
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**
```go
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**
```go
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

- gRPC Go: https://github.com/grpc/grpc-go
- Protobuf Go: https://pkg.go.dev/google.golang.org/protobuf
- gRPC error codes: https://grpc.io/docs/guides/error/

© Claude MPM Team · MIT · bobmatnyc/claude-mpm-skills

Похожие скиллы

Все скиллы по теме «Бэкенд и API» →

Сначала — golang-grpc от других авторов.

golang-grpc samber Скилл задаёт практики для gRPC в Go: от .proto и серверов до ошибок, TLS, тестов и потоковых RPC. Пригодится для разработки и ревью. CX Codex +1 39 200установок mcp-builder официальный anthropics Скилл проводит через создание MCP-сервера на TypeScript или Python: от изучения протокола до тестов и оценки качества. 130 949установок claude-api официальный anthropics Справочник по Anthropic SDK и API Claude для генерации кода без устаревших параметров и выдуманных методов. 74 198установок lark-im larksuite Скилл подключает Lark IM к агенту: он отправляет сообщения, ищет историю, управляет чатами и файлами. Подойдёт для задач вокруг командных коммуникаций. CX Codex +1 472 900установок lark-event larksuite Слушает события Lark/Feishu и отдаёт их потоком NDJSON. Подходит для ботов, обработчиков сообщений и долгих подписчиков. CX Codex +1 466 800установок caveman-discover JuliusBrussee Находит точки вызова LLM в репозитории и размечает их воркфлоу для Caveman Cloud, чтобы расходы на токены не сливались в одну общую кучу. CX Codex +1 104 400установок migration JuliusBrussee Скилл задаёт правила безопасных миграций схем, данных и API с обязательным откатом. Пригодится при изменениях, где нельзя терять данные или ломать совместимость. CX Codex +1 103 900установок

Из того же набора125

fastify Скилл для ИИ-агентов с готовыми паттернами Fastify на TypeScript: схемы, плагины, обработка ошибок, тесты через inject. CX Codex +1 571установок api-design-patterns Справочник по архитектуре REST, GraphQL и gRPC. Помогает проектировать эндпоинты, пагинацию, версионирование и схемы ошибок. CX Codex +1 566установок git-workflow Скилл с готовыми Git-паттернами: коммиты, ветки, конфликты, rebase и хуки. Пригодится, когда агент трогает версионирование. CX Codex +1 556установок express-production Скилл внедряет в проект готовую продакшн-архитектуру на Express.js. Пригодится при настройке надёжных REST API с защитными заголовками, логированием и корректным завершением процессов. CX Codex +1 508установок zustand Скилл по zustand: минимальный стейт-менеджер для React на хуках, без провайдеров и лишнего кода. Пригодится, когда глобальное состояние нужно, а Redux не хочется. CX Codex +1 485установок axum Скилл с готовыми паттернами Axum: типизированные обработчики, Tower-мидлварь, ошибки, трейсинг и корректное завершение сервера. CX Codex +1 485установок hono-core Скилл по Hono: маршрутизация, контекст, обработчики и ответы для одного кода на Cloudflare Workers, Deno, Bun и Node.js. CX Codex +1 483установок asyncio Скилл по Python asyncio: корутины, задачи, event loop, aiohttp и асинхронные эндпоинты FastAPI. Пригодится, когда код ждёт сеть или базу. CX Codex +1 476установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой