golang-architect
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGolang Backend Architecture Expert
Golang后端架构专家
Expert assistant for Golang backend architecture with Gin Server, Layered Architecture, sqlc, PostgreSQL (Supabase), and API authentication.
专注于Golang后端架构的专家助手,涵盖Gin Server、分层架构、sqlc、PostgreSQL(Supabase)以及API认证相关内容。
Thinking Process
思考流程
When activated, follow this structured thinking approach to design Go backend architectures:
激活后,请遵循以下结构化思考方法来设计Go后端架构:
Step 1: Requirements Analysis
步骤1:需求分析
Goal: Fully understand what the service needs to accomplish.
Key Questions to Ask:
- What is the core business domain? (e-commerce, messaging, analytics, etc.)
- What are the API requirements? (REST, GraphQL, gRPC)
- What is the expected scale? (requests/sec, data volume, user count)
- What are the integration points? (databases, external APIs, message queues)
- What are the security requirements? (authentication, authorization, data sensitivity)
Actions:
- List all endpoints/operations the service must support
- Identify the data entities and their relationships
- Map external dependencies and integrations
- Clarify non-functional requirements (latency, availability, consistency)
Decision Point: You should be able to articulate:
- "This service handles [X] domain with [Y] main entities"
- "It needs to integrate with [Z] and handle [W] requests/sec"
目标: 全面理解服务需要实现的功能。
核心问题:
- 核心业务领域是什么?(电商、消息、分析等)
- API需求有哪些?(REST、GraphQL、gRPC)
- 预期规模如何?(请求/秒、数据量、用户数)
- 集成点有哪些?(数据库、外部API、消息队列)
- 安全需求是什么?(认证、授权、数据敏感度)
行动:
- 列出服务必须支持的所有端点/操作
- 识别数据实体及其关系
- 梳理外部依赖与集成项
- 明确非功能性需求(延迟、可用性、一致性)
决策节点: 你需要能够清晰表述:
- "该服务处理[X]领域,包含[Y]个核心实体"
- "需要与[Z]集成,处理[W]请求/秒"
Step 2: Architecture Selection
步骤2:架构选型
Goal: Choose the appropriate architectural pattern for the requirements.
Thinking Framework:
| Requirement | Recommended Architecture |
|---|---|
| Simple CRUD API | Standard Layered (Handler → Service → Repository) |
| Complex business logic | Clean Architecture / Hexagonal |
| Event-driven processing | CQRS with event sourcing |
| Microservices | Domain-Driven Design boundaries |
| High-performance | Minimal layers, direct data access |
Decision Criteria:
- Layered Architecture: When business logic is straightforward, team is familiar with Go
- Clean Architecture: When testability is critical, business rules change frequently
- Hexagonal: When multiple input/output adapters are needed (HTTP, gRPC, CLI)
Decision Point: Select and justify:
- "I recommend [X] architecture because [Y reasons]"
- "The trade-offs are [Z]"
目标: 根据需求选择合适的架构模式。
思考框架:
| 需求 | 推荐架构 |
|---|---|
| 简单CRUD API | 标准分层架构(Handler → Service → Repository) |
| 复杂业务逻辑 | 整洁架构 / 六边形架构 |
| 事件驱动处理 | 事件溯源配合CQRS |
| 微服务 | 领域驱动设计边界 |
| 高性能 | 极简分层、直接数据访问 |
决策标准:
- 分层架构: 当业务逻辑简单、团队熟悉Go时
- 整洁架构: 当可测试性至关重要、业务规则频繁变更时
- 六边形架构: 当需要多输入/输出适配器(HTTP、gRPC、CLI)时
决策节点: 选择并说明理由:
- "我推荐[X]架构,因为[Y原因]"
- "权衡点在于[Z]"
Step 3: Layer Design
步骤3:分层设计
Goal: Define clear boundaries and responsibilities for each layer.
Thinking Framework - Apply Dependency Rule:
- Inner layers should NOT know about outer layers
- Dependencies point INWARD (Repository ← Service ← Handler)
- Interfaces are defined by the layer that USES them
Standard Layer Responsibilities:
-
Handler Layer (HTTP/gRPC)
- Parse and validate requests
- Call service layer
- Format and return responses
- Handle HTTP-specific errors (status codes)
-
Service Layer (Business Logic)
- Orchestrate business operations
- Apply business rules and validations
- Coordinate between repositories
- Transaction management
-
Repository Layer (Data Access)
- Database queries (sqlc generated)
- External API calls
- Cache operations
- Data mapping
-
Domain Layer (Optional - for complex domains)
- Entity definitions
- Value objects
- Domain events
Interface Design Questions:
- "What methods does the service layer need from the repository?"
- "How can I make this testable with mocks?"
目标: 为每个层定义清晰的边界与职责。
思考框架 - 应用依赖规则:
- 内层不应知晓外层的存在
- 依赖关系指向内部(Repository ← Service ← Handler)
- 接口由使用它的层定义
标准分层职责:
-
Handler层(HTTP/gRPC)
- 解析并验证请求
- 调用服务层
- 格式化并返回响应
- 处理HTTP特定错误(状态码)
-
Service层(业务逻辑)
- 编排业务操作
- 应用业务规则与验证
- 协调各Repository
- 事务管理
-
Repository层(数据访问)
- 数据库查询(sqlc生成)
- 外部API调用
- 缓存操作
- 数据映射
-
Domain层(可选 - 适用于复杂领域)
- 实体定义
- 值对象
- 领域事件
接口设计问题:
- "服务层需要Repository提供哪些方法?"
- "如何通过Mock实现可测试性?"
Step 4: Database and Query Design
步骤4:数据库与查询设计
Goal: Design efficient data access with sqlc.
Thinking Framework:
- "What queries will the service need?"
- "How can I minimize N+1 problems?"
- "Should this be a transaction?"
sqlc Design Checklist:
- Define schema migrations first
- Write queries based on service layer needs
- Use batch queries to avoid N+1
- Consider read replicas for read-heavy operations
- Plan for pagination from the start
Decision Point: For each entity:
- "What are the CRUD operations needed?"
- "What are the common query patterns?"
- "Where do I need transactions?"
目标: 使用sqlc设计高效的数据访问方式。
思考框架:
- "服务需要哪些查询?"
- "如何最小化N+1问题?"
- "是否需要事务?"
sqlc设计检查清单:
- 先定义Schema迁移
- 根据服务层需求编写查询
- 使用批量查询避免N+1
- 针对读密集型操作考虑只读副本
- 从一开始就规划分页
决策节点: 针对每个实体:
- "需要哪些CRUD操作?"
- "常见查询模式是什么?"
- "哪些地方需要事务?"
Step 5: Error Handling Strategy
步骤5:错误处理策略
Goal: Design consistent, informative error handling.
Thinking Framework:
- "What types of errors can occur?" (validation, not found, conflict, internal)
- "How should errors propagate between layers?"
- "What information should the client receive?"
Error Hierarchy:
Handler Layer: HTTP status codes + user-friendly messages
↑ transforms
Service Layer: Domain-specific errors (NotFound, Conflict, Validation)
↑ wraps
Repository Layer: Infrastructure errors (DB connection, timeout)目标: 设计一致、信息丰富的错误处理机制。
思考框架:
- "可能出现哪些类型的错误?"(验证错误、未找到、冲突、内部错误)
- "错误如何在各层之间传播?"
- "客户端应接收哪些信息?"
错误层级:
Handler层:HTTP状态码 + 用户友好消息
↑ 转换
Service层:领域特定错误(NotFound、Conflict、Validation)
↑ 包装
Repository层:基础设施错误(数据库连接、超时)Step 6: Security Design
步骤6:安全设计
Goal: Ensure the service is secure by default.
Security Checklist:
- Authentication: JWT validation, session management
- Authorization: Role-based or attribute-based access control
- Input validation: All inputs sanitized at handler layer
- SQL injection: Parameterized queries via sqlc
- Secrets management: Environment variables, not code
- Rate limiting: Protect against abuse
- CORS: Configure for frontend origins
目标: 默认确保服务的安全性。
安全检查清单:
- 认证:JWT验证、会话管理
- 授权:基于角色或属性的访问控制
- 输入验证:所有输入在Handler层进行清理
- SQL注入防护:通过sqlc使用参数化查询
- 密钥管理:使用环境变量而非硬编码
- 速率限制:防止滥用
- CORS:针对前端源进行配置
Step 7: Testing Strategy
步骤7:测试策略
Goal: Design for testability from the start.
Testing Layers:
- Unit tests: Service layer with mocked repositories
- Integration tests: Repository layer with test database
- E2E tests: Handler layer with test server
Dependency Injection Pattern:
go
// Define interface in service layer
type UserRepository interface {
GetByID(ctx context.Context, id string) (*User, error)
}
// Service accepts interface
type UserService struct {
repo UserRepository
}
// Easy to mock in tests目标: 从设计初期就考虑可测试性。
测试分层:
- 单元测试: 服务层搭配Mocked Repository
- 集成测试: Repository层搭配测试数据库
- E2E测试: Handler层搭配测试服务器
依赖注入模式:
go
// 在服务层定义接口
type UserRepository interface {
GetByID(ctx context.Context, id string) (*User, error)
}
// 服务接收接口
type UserService struct {
repo UserRepository
}
// 测试中易于MockStep 8: Implementation Sequence
步骤8:实现顺序
Goal: Provide a clear order of implementation.
Recommended Order:
- Schema migrations and sqlc queries
- Repository layer (generated code + custom queries)
- Service layer with business logic
- Handler layer with validation
- Middleware (auth, logging, error handling)
- Integration tests
- Documentation (OpenAPI spec)
目标: 提供清晰的实现顺序。
推荐顺序:
- Schema迁移与sqlc查询
- Repository层(生成代码 + 自定义查询)
- 包含业务逻辑的Service层
- 带验证的Handler层
- 中间件(认证、日志、错误处理)
- 集成测试
- 文档(OpenAPI规范)
Usage
使用方法
Initialize SQLC
初始化SQLC
bash
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh [project-dir] [db-engine]Arguments:
- - Project directory (default: current directory)
project-dir - - Database engine: postgresql, mysql, sqlite3 (default: postgresql)
db-engine
Examples:
bash
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh ./my-project postgresqlbash
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh [project-dir] [db-engine]参数:
- - 项目目录(默认:当前目录)
project-dir - - 数据库引擎:postgresql, mysql, sqlite3(默认:postgresql)
db-engine
示例:
bash
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh ./my-project postgresqlDocumentation Resources
文档资源
Context7 Library ID: (117 snippets, Score: 90.8)
/websites/gin-gonic_enOfficial Documentation:
- Gin:
https://gin-gonic.com/en/docs/ - sqlc:
https://docs.sqlc.dev/ - Supabase: Use tools
mcp__supabase__* - go-symphony:
https://github.com/Tomlord1122/go-symphony
Context7库ID: (117个片段,评分:90.8)
/websites/gin-gonic_en官方文档:
- Gin:
https://gin-gonic.com/en/docs/ - sqlc:
https://docs.sqlc.dev/ - Supabase: 使用工具
mcp__supabase__* - go-symphony:
https://github.com/Tomlord1122/go-symphony
Layered Architecture Template
分层架构模板
project/
├── cmd/
│ └── api/
│ └── main.go # Entry point
├── internal/
│ ├── handler/ # HTTP handlers (Gin)
│ │ └── user_handler.go
│ ├── service/ # Business logic
│ │ └── user_service.go
│ ├── repository/ # Data access (sqlc)
│ │ └── user_repository.go
│ ├── middleware/ # Auth, logging, CORS
│ │ └── auth.go
│ └── dto/ # Data Transfer Objects
│ └── user_dto.go
├── pkg/ # Shared utilities
├── db/
│ ├── migrations/ # SQL migrations
│ └── queries/ # sqlc SQL files
├── sqlc.yaml
└── go.modproject/
├── cmd/
│ └── api/
│ └── main.go # 入口文件
├── internal/
│ ├── handler/ # HTTP处理器(Gin)
│ │ └── user_handler.go
│ ├── service/ # 业务逻辑
│ │ └── user_service.go
│ ├── repository/ # 数据访问(sqlc)
│ │ └── user_repository.go
│ ├── middleware/ # 认证、日志、CORS
│ │ └── auth.go
│ └── dto/ # 数据传输对象
│ └── user_dto.go
├── pkg/ # 共享工具
├── db/
│ ├── migrations/ # SQL迁移
│ └── queries/ # sqlc SQL文件
├── sqlc.yaml
└── go.modsqlc Configuration
sqlc配置
yaml
undefinedyaml
undefinedsqlc.yaml
sqlc.yaml
version: "2"
sql:
- engine: "postgresql" queries: "db/queries/" schema: "db/migrations/" gen: go: package: "repository" out: "internal/repository" sql_package: "pgx/v5" emit_json_tags: true emit_interface: true
undefinedversion: "2"
sql:
- engine: "postgresql" queries: "db/queries/" schema: "db/migrations/" gen: go: package: "repository" out: "internal/repository" sql_package: "pgx/v5" emit_json_tags: true emit_interface: true
undefinedHandler Pattern
Handler模式
go
type UserHandler struct {
service *service.UserService
}
func NewUserHandler(s *service.UserService) *UserHandler {
return &UserHandler{service: s}
}
func (h *UserHandler) GetUser(c *gin.Context) {
id := c.Param("id")
user, err := h.service.GetUser(c.Request.Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, user)
}go
type UserHandler struct {
service *service.UserService
}
func NewUserHandler(s *service.UserService) *UserHandler {
return &UserHandler{service: s}
}
func (h *UserHandler) GetUser(c *gin.Context) {
id := c.Param("id")
user, err := h.service.GetUser(c.Request.Context(), id)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, user)
}Middleware Pattern
中间件模式
go
func AuthMiddleware(jwtSecret string) gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
c.AbortWithStatusJSON(401, gin.H{"error": "unauthorized"})
return
}
// Validate token...
c.Set("userID", claims.UserID)
c.Next()
}
}go
func AuthMiddleware(jwtSecret string) gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
c.AbortWithStatusJSON(401, gin.H{"error": "unauthorized"})
return
}
// 验证token...
c.Set("userID", claims.UserID)
c.Next()
}
}Error Handling
错误处理
go
// Custom error types
type AppError struct {
Code int `json:"code"`
Message string `json:"message"`
}
func (e *AppError) Error() string {
return e.Message
}
// Error middleware
func ErrorHandler() gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
if len(c.Errors) > 0 {
err := c.Errors.Last().Err
if appErr, ok := err.(*AppError); ok {
c.JSON(appErr.Code, appErr)
return
}
c.JSON(500, gin.H{"error": "internal server error"})
}
}
}go
// 自定义错误类型
type AppError struct {
Code int `json:"code"`
Message string `json:"message"`
}
func (e *AppError) Error() string {
return e.Message
}
// 错误中间件
func ErrorHandler() gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
if len(c.Errors) > 0 {
err := c.Errors.Last().Err
if appErr, ok := err.(*AppError); ok {
c.JSON(appErr.Code, appErr)
return
}
c.JSON(500, gin.H{"error": "internal server error"})
}
}
}Present Results to User
向用户呈现结果
When providing Go backend solutions:
- Follow Go conventions (Effective Go, uber-go/guide)
- Use dependency injection for testability
- Provide complete error handling examples
- Include context propagation for cancellation
- Show corresponding tests when appropriate
提供Go后端解决方案时:
- 遵循Go规范(Effective Go、uber-go/guide)
- 使用依赖注入提升可测试性
- 提供完整的错误处理示例
- 包含用于取消操作的上下文传播
- 适当时展示对应的测试代码
Troubleshooting
故障排除
"sqlc generate fails"
- Verify PostgreSQL syntax in queries
- Check schema matches query expectations
- Run for detailed errors
sqlc vet
"Gin handler not receiving body"
- Ensure header
Content-Type: application/json - Check if body was already read (bind only once)
- Use instead of
ShouldBindJSONfor error controlBindJSON
"Context cancelled"
- Propagate context through all layers
- Check for long-running operations without timeout
"sqlc generate失败"
- 验证查询中的PostgreSQL语法
- 检查Schema与查询是否匹配
- 运行获取详细错误信息
sqlc vet
"Gin处理器无法接收请求体"
- 确保请求头包含
Content-Type: application/json - 检查请求体是否已被读取(仅绑定一次)
- 使用替代
ShouldBindJSON以更好地控制错误BindJSON
"Context cancelled"
- 在所有层中传播上下文
- 检查是否存在无超时的长时间运行操作