golang-architect

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Golang 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:
  1. List all endpoints/operations the service must support
  2. Identify the data entities and their relationships
  3. Map external dependencies and integrations
  4. 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、消息队列)
  • 安全需求是什么?(认证、授权、数据敏感度)
行动:
  1. 列出服务必须支持的所有端点/操作
  2. 识别数据实体及其关系
  3. 梳理外部依赖与集成项
  4. 明确非功能性需求(延迟、可用性、一致性)
决策节点: 你需要能够清晰表述:
  • "该服务处理[X]领域,包含[Y]个核心实体"
  • "需要与[Z]集成,处理[W]请求/秒"

Step 2: Architecture Selection

步骤2:架构选型

Goal: Choose the appropriate architectural pattern for the requirements.
Thinking Framework:
RequirementRecommended Architecture
Simple CRUD APIStandard Layered (Handler → Service → Repository)
Complex business logicClean Architecture / Hexagonal
Event-driven processingCQRS with event sourcing
MicroservicesDomain-Driven Design boundaries
High-performanceMinimal 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:
  1. Handler Layer (HTTP/gRPC)
    • Parse and validate requests
    • Call service layer
    • Format and return responses
    • Handle HTTP-specific errors (status codes)
  2. Service Layer (Business Logic)
    • Orchestrate business operations
    • Apply business rules and validations
    • Coordinate between repositories
    • Transaction management
  3. Repository Layer (Data Access)
    • Database queries (sqlc generated)
    • External API calls
    • Cache operations
    • Data mapping
  4. 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)
  • 接口由使用它的层定义
标准分层职责:
  1. Handler层(HTTP/gRPC)
    • 解析并验证请求
    • 调用服务层
    • 格式化并返回响应
    • 处理HTTP特定错误(状态码)
  2. Service层(业务逻辑)
    • 编排业务操作
    • 应用业务规则与验证
    • 协调各Repository
    • 事务管理
  3. Repository层(数据访问)
    • 数据库查询(sqlc生成)
    • 外部API调用
    • 缓存操作
    • 数据映射
  4. 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:
  1. Define schema migrations first
  2. Write queries based on service layer needs
  3. Use batch queries to avoid N+1
  4. Consider read replicas for read-heavy operations
  5. 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设计检查清单:
  1. 先定义Schema迁移
  2. 根据服务层需求编写查询
  3. 使用批量查询避免N+1
  4. 针对读密集型操作考虑只读副本
  5. 从一开始就规划分页
决策节点: 针对每个实体:
  • "需要哪些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
}

// 测试中易于Mock

Step 8: Implementation Sequence

步骤8:实现顺序

Goal: Provide a clear order of implementation.
Recommended Order:
  1. Schema migrations and sqlc queries
  2. Repository layer (generated code + custom queries)
  3. Service layer with business logic
  4. Handler layer with validation
  5. Middleware (auth, logging, error handling)
  6. Integration tests
  7. Documentation (OpenAPI spec)
目标: 提供清晰的实现顺序。
推荐顺序:
  1. Schema迁移与sqlc查询
  2. Repository层(生成代码 + 自定义查询)
  3. 包含业务逻辑的Service层
  4. 带验证的Handler层
  5. 中间件(认证、日志、错误处理)
  6. 集成测试
  7. 文档(OpenAPI规范)

Usage

使用方法

Initialize SQLC

初始化SQLC

bash
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh [project-dir] [db-engine]
Arguments:
  • project-dir
    - Project directory (default: current directory)
  • db-engine
    - Database engine: postgresql, mysql, sqlite3 (default: postgresql)
Examples:
bash
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh ./my-project postgresql
bash
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh [project-dir] [db-engine]
参数:
  • project-dir
    - 项目目录(默认:当前目录)
  • db-engine
    - 数据库引擎:postgresql, mysql, sqlite3(默认:postgresql)
示例:
bash
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh
bash /mnt/skills/user/golang-architect/scripts/sqlc-init.sh ./my-project postgresql

Documentation Resources

文档资源

Context7 Library ID:
/websites/gin-gonic_en
(117 snippets, Score: 90.8)
Official Documentation:
  • Gin:
    https://gin-gonic.com/en/docs/
  • sqlc:
    https://docs.sqlc.dev/
  • Supabase: Use
    mcp__supabase__*
    tools
  • go-symphony:
    https://github.com/Tomlord1122/go-symphony
Context7库ID:
/websites/gin-gonic_en
(117个片段,评分:90.8)
官方文档:
  • 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.mod
project/
├── 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.mod

sqlc Configuration

sqlc配置

yaml
undefined
yaml
undefined

sqlc.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
undefined
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
undefined

Handler 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
    sqlc vet
    for detailed errors
"Gin handler not receiving body"
  • Ensure
    Content-Type: application/json
    header
  • Check if body was already read (bind only once)
  • Use
    ShouldBindJSON
    instead of
    BindJSON
    for error control
"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"
  • 在所有层中传播上下文
  • 检查是否存在无超时的长时间运行操作