10 KiB
GitHub Copilot Instructions for go-zero
This document provides guidelines for GitHub Copilot when assisting with development in the go-zero project.
Project Overview
go-zero is a web and RPC framework with lots of built-in engineering practices designed to ensure the stability of busy services with resilience design. It has been serving sites with tens of millions of users for years.
Key Architecture Components
- REST API framework (
rest/) - HTTP service framework with middleware chain support - RPC framework (
zrpc/) - gRPC-based RPC framework with etcd service discovery and p2c_ewma load balancing - Gateway (
gateway/) - API gateway supporting both HTTP and gRPC upstreams with proto-based routing - MCP Server (
mcp/) - Model Context Protocol server for AI agent integration via SSE - Core utilities (
core/) - Production-grade components:- Resilience: circuit breakers (
breaker/), rate limiters (limit/), adaptive load shedding (load/) - Storage: SQL with cache (
stores/sqlc/), Redis (stores/redis/), MongoDB (stores/mongo/) - Concurrency: MapReduce (
mr/), worker pools (executors/), sync primitives (syncx/) - Observability: metrics (
metric/), tracing (trace/), structured logging (logx/)
- Resilience: circuit breakers (
- Code generation tool (
tools/goctl/) - CLI tool for generating Go code from.apiand.protofiles
Coding Standards and Conventions
Code Style
- Follow Go conventions: Use
gofmtfor formatting, follow effective Go practices - Package naming: Use lowercase, single-word package names when possible
- Error handling: Always handle errors explicitly, use
errorx.BatchErrorfor multiple errors - Context propagation: Always pass
context.Contextas the first parameter for functions that may block - Configuration structures: Use struct tags with JSON annotations, defaults, and validation
Pattern: All service configs embed service.ServiceConf for common fields (Name, Log, Mode, Telemetry)
type Config struct {
service.ServiceConf // Always embed for services
Host string `json:",default=0.0.0.0"`
Port int // Required field (no default)
Timeout int64 `json:",default=3000"` // Timeouts in milliseconds
Optional string `json:",optional"` // Optional field
Mode string `json:",default=pro,options=dev|test|rt|pre|pro"` // Validated options
}
Service modes: dev/test/rt disable load shedding and stats; pre/pro enable all resilience features
Interface Design
- Small interfaces: Follow Go's preference for small, focused interfaces
- Context methods: Provide both context and non-context versions of methods
- Options pattern: Use functional options for complex configuration
Example:
func (c *Client) Get(key string, val any) error {
return c.GetCtx(context.Background(), key, val)
}
func (c *Client) GetCtx(ctx context.Context, key string, val any) error {
// implementation
}
Testing Patterns
- Test file naming: Use
*_test.gosuffix - Test function naming: Use
TestFunctionNamepattern - Use testify/assert: Prefer
assertpackage for assertions - Table-driven tests: Use table-driven tests for multiple scenarios
- Mock interfaces: Use
go.uber.org/mockfor mocking - Test helpers: Use
redistest,mongtesthelpers for database testing
Example test pattern:
func TestSomething(t *testing.T) {
tests := []struct {
name string
input string
expected string
wantErr bool
}{
{"valid case", "input", "output", false},
{"error case", "bad", "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := SomeFunction(tt.input)
if tt.wantErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)
assert.Equal(t, tt.expected, result)
})
}
}
Framework-Specific Guidelines
REST API Development
- API Definition: Use
.apifiles to define REST APIs with goctl codegen - Handler pattern: Separate business logic into logic packages (handlers call logic layer)
- Middleware chain: Middlewares wrap via
chain.Chaininterface - useAppend()orPrepend()to control order- Built-in middlewares (all in
rest/handler/): tracing, logging, metrics, recovery, breaker, shedding, timeout, maxconns, maxbytes, gunzip - Custom middleware:
func(http.Handler) http.Handler- callnext.ServeHTTP(w, r)to continue chain
- Built-in middlewares (all in
- Response handling: Use
httpx.WriteJson(w, code, v)for JSON responses - Error handling: Use
httpx.Error(w, err)orhttpx.ErrorCtx(ctx, w, err)for HTTP error responses - Route registration: Routes defined with
Method,Path, andHandler- wildcards use:paramsyntax
RPC Development
- Protocol Buffers: Use protobuf for service definitions, generate code with goctl
- Service discovery: Use etcd for dynamic service registration/discovery, or direct endpoints for static routing
- Load balancing: Default is
p2c_ewma(power of 2 choices with EWMA), configurable viaBalancerName - Client configuration: Support
Etcd,Endpoints, orTarget- useBuildTarget()to construct connection string - Interceptors: Implement gRPC interceptors for cross-cutting concerns (auth, logging, metrics)
- Health checks: gRPC health checks enabled by default (
Health: true)
Database Operations
- SQL operations: Use
sqlx.SqlConninterface - methods always end withCtxfor context support - Caching pattern:
stores/sqlcprovidesCachedConnfor automatic cache-aside patternQueryRowCtx: Query with cache key, auto-populate on cache missExecCtx: Execute and delete cache keys
- Transactions: Use
sqlx.SqlConn.TransactCtx()to get transaction session - Connection pooling: Managed automatically (64 max idle/open, 1min lifetime)
- Test helpers: Use
redistest.CreateRedis(t)for Redis, SQL mocks for DB testing
Example cache pattern:
err := c.QueryRowCtx(ctx, &dest, key, func(ctx context.Context, conn sqlx.SqlConn) error {
return conn.QueryRowCtx(ctx, &dest, query, args...)
})
Configuration Management
- YAML configuration: Use YAML for configuration files
- Environment variables: Support environment variable overrides
- Validation: Include proper validation for configuration parameters
- Sensible defaults: Provide reasonable default values
Error Handling Best Practices
- Wrap errors: Use
fmt.Errorfwith%wverb to wrap errors - Custom errors: Define custom error types when needed
- Error logging: Log errors appropriately with context
- Graceful degradation: Implement fallback mechanisms
Performance Considerations
- Resource pools: Use connection pools and worker pools
- Circuit breakers: Implement circuit breaker patterns for external calls
- Rate limiting: Apply rate limiting to protect services
- Load shedding: Implement adaptive load shedding
- Metrics: Add appropriate metrics and monitoring
Security Guidelines
- Input validation: Validate all input parameters
- SQL injection prevention: Use parameterized queries
- Authentication: Implement proper JWT token handling
- HTTPS: Support TLS/HTTPS configurations
- CORS: Configure CORS appropriately for web APIs
Documentation Standards
- Package documentation: Include package-level documentation
- Function documentation: Document exported functions with examples
- API documentation: Maintain API documentation in sync
- README updates: Update README for significant changes
Common Patterns to Follow
Service Configuration
type ServiceConf struct {
Name string
Log logx.LogConf
Mode string `json:",default=pro,options=[dev,test,pre,pro]"`
// ... other common fields
}
Middleware Implementation
func SomeMiddleware() rest.Middleware {
return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Pre-processing
next.ServeHTTP(w, r)
// Post-processing
}
}
}
Resource Management
Always implement proper resource cleanup using defer and context cancellation.
Build and Test Commands
- Build:
go build ./... - Test:
go test ./... - Test with race detection:
go test -race ./... - Format:
gofmt -w . - Code generation:
- REST API:
goctl api go -api *.api -dir . - RPC:
goctl rpc protoc *.proto --go_out=. --go-grpc_out=. --zrpc_out=. - Model from SQL:
goctl model mysql datasource -url="user:pass@tcp(host:port)/db" -table="*" -dir="./model"
- REST API:
Critical Architecture Patterns
Resilience Design Philosophy
go-zero implements defense-in-depth with multiple protection layers:
- Circuit Breaker (
core/breaker): Google SRE breaker - tracks success/failure, opens on error threshold - Adaptive Load Shedding (
core/load): CPU-based auto-rejection when system overloaded (disabled in dev/test/rt modes) - Rate Limiting (
core/limit): Token bucket (Redis-based) and period limiters - Timeout Control: Cascading timeouts via context - set at multiple levels (client, server, handler)
Middleware Chain Architecture
rest/chain provides middleware composition:
// Middleware signature
type Middleware func(http.Handler) http.Handler
// Chain operations
chain := chain.New(m1, m2)
chain.Append(m3) // Adds to end: m1 -> m2 -> m3
chain.Prepend(m0) // Adds to start: m0 -> m1 -> m2 -> m3
handler := chain.Then(finalHandler)
Concurrency Patterns
- MapReduce (
core/mr): Parallel processing with worker pools - use for batch operations - Executors (
core/executors): Bulk/period executors for batching operations - SingleFlight (
core/syncx): Deduplicates concurrent identical requests
Remember to run tests and ensure all checks pass before submitting changes. The project emphasizes high quality, performance, and reliability, so these should be primary considerations in all development work.