This skill covers best practices for building gRPC-based services and APIs using Protocol Buffers, including service design, streaming patterns, interceptors, security, and observability.
.proto files with service definitions, RPC methods, and message types following the style and naming conventions below.protoc with the appropriate language plugin (e.g., protoc-gen-go-grpc, grpcio-tools) to produce server and client code.optional for fields that may not always be presentoneof when users need to choose between mutually exclusive optionsSTATUS_UNSPECIFIED = 0)ORDER_STATUS_CREATED vs STATUS_PENDING)syntax = "proto3";
package order.v1;
option go_package = "gen/order/v1;orderv1";
// OrderService manages customer orders.
service OrderService {
// Creates a new order and returns the created resource.
rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse);
// Streams real-time status updates for an order.
rpc WatchOrder(WatchOrderRequest) returns (stream OrderStatus);
}
message CreateOrderRequest {
string customer_id = 1;
repeated OrderItem items = 2;
}
message CreateOrderResponse {
string order_id = 1;
OrderStatus status = 2;
}
message WatchOrderRequest {
string order_id = 1;
}
message OrderItem {
string product_id = 1;
int32 quantity = 2;
}
message OrderStatus {
string order_id = 1;
OrderState state = 2;
string updated_at = 3;
}
enum OrderState {
ORDER_STATE_UNSPECIFIED = 0;
ORDER_STATE_CREATED = 1;
ORDER_STATE_PROCESSING = 2;
ORDER_STATE_SHIPPED = 3;
ORDER_STATE_DELIVERED = 4;
}
package main
import (
"context"
"log"
"net"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
pb "example.com/gen/order/v1"
)
type orderServer struct {
pb.UnimplementedOrderServiceServer
}
func (s *orderServer) CreateOrder(ctx context.Context, req *pb.CreateOrderRequest) (*pb.CreateOrderResponse, error) {
if req.GetCustomerId() == "" {
return nil, status.Error(codes.InvalidArgument, "customer_id is required")
}
orderID := "ord-" + time.Now().Format("20060102150405")
return &pb.CreateOrderResponse{
OrderId: orderID,
Status: &pb.OrderStatus{
OrderId: orderID,
State: pb.OrderState_ORDER_STATE_CREATED,
},
}, nil
}
func (s *orderServer) WatchOrder(req *pb.WatchOrderRequest, stream pb.OrderService_WatchOrderServer) error {
for i, state := range []pb.OrderState{
pb.OrderState_ORDER_STATE_PROCESSING,
pb.OrderState_ORDER_STATE_SHIPPED,
pb.OrderState_ORDER_STATE_DELIVERED,
} {
select {
case <-stream.Context().Done():
return stream.Context().Err()
case <-time.After(time.Duration(i) * time.Second):
if err := stream.Send(&pb.OrderStatus{
OrderId: req.GetOrderId(),
State: state,
UpdatedAt: time.Now().Format(time.RFC3339),
}); err != nil {
return err
}
}
}
return nil
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
srv := grpc.NewServer(
grpc.UnaryInterceptor(loggingUnaryInterceptor),
)
pb.RegisterOrderServiceServer(srv, &orderServer{})
log.Println("serving on :50051")
if err := srv.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
// loggingUnaryInterceptor logs each unary RPC call.
func loggingUnaryInterceptor(
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 err=%v", info.FullMethod, time.Since(start), err)
return resp, err
}
google.golang.org/grpc packageprotoc-gen-go-grpcgrpcio and grpcio-tools packagesgrpcio-aio for better concurrency@grpc/grpc-js (pure JavaScript implementation)nice-grpc for better TypeScript supportCreate or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Set up and use 1Password CLI (op). Use when installing the CLI, enabling desktop app integration, signing in (single or multi-account), or reading/injecting/running secrets via op.
CLI to manage emails via IMAP/SMTP. Use `himalaya` to list, read, write, reply, forward, search, and organize emails from the terminal. Supports multiple accounts and message composition with MML (MIME Meta Language).
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Set up and use 1Password CLI (op). Use when installing the CLI, enabling desktop app integration, signing in (single or multi-account), or reading/injecting/running secrets via op.
CLI to manage emails via IMAP/SMTP. Use `himalaya` to list, read, write, reply, forward, search, and organize emails from the terminal. Supports multiple accounts and message composition with MML (MIME Meta Language).