go-grpc
О программе
Этот навык Claude предоставляет расширенное руководство по реализации готовых к эксплуатации gRPC-сервисов на Go. Он охватывает проектирование proto-файлов, обработку ошибок, перехватчики, потоковую передачу данных, таймауты, проверки работоспособности и плавное завершение работы. Используйте его конкретно для реализации gRPC-сервисов, а не для REST API, общей архитектуры или усиления безопасности.
Быстрая установка
Claude Code
Рекомендуетсяnpx skills add eduardo-sl/go-agent-skills -a claude-code/plugin add https://github.com/eduardo-sl/go-agent-skillsgit clone https://github.com/eduardo-sl/go-agent-skills.git ~/.claude/skills/go-grpcСкопируйте и вставьте эту команду в Claude Code для установки этого навыка
Документация
Go gRPC Services
gRPC's contract-first model only pays off if the contract is treated as an API: versioned packages, deliberate error codes, deadlines everywhere, and interceptors for everything cross-cutting.
1. Proto Design Rules
syntax = "proto3";
package payment.v1; // version IN the package
option go_package = "github.com/acme/payment-service/gen/payment/v1;paymentv1";
service PaymentService {
rpc CreatePayment(CreatePaymentRequest) returns (CreatePaymentResponse);
}
message CreatePaymentRequest { // one request/response pair
string order_id = 1; // per RPC, always — even if
int64 amount_cents = 2; // empty today
}
message CreatePaymentResponse {
Payment payment = 1;
}
- Version in the package (
payment.v1); breaking change =payment.v2. - Never reuse or renumber field tags;
reserved 3, 7;deleted ones. - Dedicated Request/Response messages per RPC — adding a field later is free; changing a shared message breaks every RPC using it.
- Generate with buf or a pinned protoc in
make generate; commit generated code so builds don't depend on toolchain drift.
2. Errors: Status Codes, Not Strings
Return status.Error, mapping domain errors in ONE place:
func (s *Server) CreatePayment(ctx context.Context, req *pb.CreatePaymentRequest) (*pb.CreatePaymentResponse, error) {
p, err := s.svc.Create(ctx, toDomain(req))
if err != nil {
return nil, toStatus(err)
}
return &pb.CreatePaymentResponse{Payment: fromDomain(p)}, nil
}
func toStatus(err error) error {
switch {
case errors.Is(err, domain.ErrNotFound):
return status.Error(codes.NotFound, "payment not found")
case errors.Is(err, domain.ErrDuplicate):
return status.Error(codes.AlreadyExists, "payment already exists")
case errors.Is(err, context.DeadlineExceeded):
return status.Error(codes.DeadlineExceeded, "timed out")
default:
return status.Error(codes.Internal, "internal error") // no details leak
}
}
Code semantics that matter: InvalidArgument (bad request regardless
of state), FailedPrecondition (bad state), NotFound, AlreadyExists,
Unauthenticated vs PermissionDenied, Unavailable (retryable),
Internal (bug). Clients read codes with status.FromError(err) —
never parse messages.
3. Deadlines Are Mandatory
// Client — every call gets a deadline
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()
resp, err := client.CreatePayment(ctx, req)
// Server — check before expensive work
if err := ctx.Err(); err != nil {
return nil, status.FromContextError(err).Err()
}
The server inherits the client's deadline through the context. Pass
ctx into every downstream call (DB, other RPCs) so cancellation
propagates end to end.
4. Interceptors for Cross-Cutting Concerns
Handlers stay business-only; recovery, auth, logging, metrics live in interceptors:
srv := grpc.NewServer(
grpc.ChainUnaryInterceptor(
recoveryInterceptor, // outermost: panic → codes.Internal
loggingInterceptor,
authInterceptor,
),
)
func loggingInterceptor(ctx context.Context, req any,
info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
start := time.Now()
resp, err := handler(ctx, req)
slog.InfoContext(ctx, "rpc",
slog.String("method", info.FullMethod),
slog.Duration("duration", time.Since(start)),
slog.String("code", status.Code(err).String()),
)
return resp, err
}
Order matters: recovery first (outermost), then observability, then
auth. Streaming RPCs need the parallel StreamInterceptor versions.
5. Streaming
- Server streaming for large result sets:
stream.Sendin a loop, return non-nil error to abort with a status. - Client/bidi streaming only when the protocol truly needs it — each open stream holds a goroutine and flow-control state.
- Always terminate on
ctx.Done():
func (s *Server) WatchPayments(req *pb.WatchRequest, stream pb.PaymentService_WatchPaymentsServer) error {
for {
select {
case <-stream.Context().Done():
return status.FromContextError(stream.Context().Err()).Err()
case ev := <-s.events:
if err := stream.Send(toProto(ev)); err != nil {
return err
}
}
}
}
6. Production Server Setup
lis, err := net.Listen("tcp", cfg.Addr)
if err != nil {
return fmt.Errorf("listen: %w", err)
}
srv := grpc.NewServer(grpc.ChainUnaryInterceptor(...))
pb.RegisterPaymentServiceServer(srv, server)
healthSrv := health.NewServer() // grpc.health.v1 — load balancers need it
healthpb.RegisterHealthServer(srv, healthSrv)
reflection.Register(srv) // grpcurl/debugging; gate on non-prod if policy requires
go func() {
<-ctx.Done()
stopped := make(chan struct{})
go func() { srv.GracefulStop(); close(stopped) }()
select {
case <-stopped: // in-flight RPCs finished
case <-time.After(10 * time.Second):
srv.Stop() // force after grace period
}
}()
return srv.Serve(lis)
Verification Checklist
- Proto packages versioned (
*.v1); no tag reuse;reservedfor removals - Dedicated Request/Response message per RPC
- Generated code produced by a pinned tool (buf/protoc) and committed
- All handler errors are
status.Errorwith semantically correct codes codes.Internalresponses never leak internal error text- Every client call has a deadline; ctx propagated through all layers
- Recovery, logging, auth implemented as chained interceptors (unary + stream)
- Streams select on
stream.Context().Done() - Health service registered; graceful stop with forced fallback
grpcurlsmoke test (or generated client test) passes against the running server
GitHub репозиторий
Часто задаваемые вопросы
Что такое Skill go-grpc?
go-grpc — это Claude Skill от eduardo-sl. Skills объединяют инструкции и ресурсы, которые Claude загружает по мере необходимости, чтобы выполнять задачи, связанные с go-grpc, без дополнительных запросов.
Как установить go-grpc?
Используйте команды установки на этой странице: добавьте go-grpc в Claude Code как плагин или клонируйте репозиторий в каталог skills, затем перезапустите Claude, чтобы загрузить Skill.
К какой категории относится go-grpc?
go-grpc относится к категории Дизайн.
Можно ли использовать go-grpc бесплатно?
Да. go-grpc размещён на AIMCP и доступен для бесплатной установки.
Похожие навыки
Используйте навык executing-plans, когда у вас есть полный план реализации для выполнения контролируемыми партиями с контрольными точками проверки. Он загружает и критически анализирует план, затем выполняет задачи небольшими партиями (по умолчанию 3 задачи), сообщая о прогрессе между каждой партией для проверки архитектором. Это обеспечивает систематическую реализацию со встроенными контрольными точками проверки качества.
Этот навык запускает суб-агента для ревью кода, который анализирует изменения в коде на соответствие требованиям перед дальнейшими действиями. Его следует использовать после завершения задач, реализации крупных функций или перед слиянием с основной веткой. Ревью помогает выявить проблемы на ранней стадии, сравнивая текущую реализацию с исходным планом.
Этот навык предоставляет разработчикам подробное руководство по подключению серверов MCP к Claude Code с использованием транспортов HTTP, stdio или SSE. Он охватывает установку, конфигурацию, аутентификацию и безопасность для интеграции внешних сервисов, таких как GitHub, Notion и пользовательские API. Используйте его при настройке интеграций MCP, конфигурации внешних инструментов или работе с Model Context Protocol от Claude.
Этот навык помогает разработчикам выбирать между веб-интерфейсом Claude Code и CLI на основе анализа задачи, а также обеспечивает бесшовное перемещение сессий между этими средами. Он оптимизирует рабочий процесс, управляя состоянием и контекстом сессии при переключении между веб-интерфейсом, CLI или мобильным приложением. Используйте его для сложных проектов, требующих различных инструментов на разных этапах работы.
