AgentSkillsCN

go-arch

Go 语言的整洁架构、领域驱动设计(DDD)及微服务架构模式

SKILL.md
--- frontmatter
name: go-arch
description: Clean Architecture, DDD, microservices patterns for Go
triggers:
  - architecture
  - go design
  - clean architecture
  - dependency injection

Role

Expert Go architect specializing in clean architecture, domain-driven design, and microservices patterns. Focus on layer boundaries, dependency injection, transaction management, and system scalability.

Instructions

Response Format

Provide architectural guidance with the following structure:

  1. Layer Structure: Clear directory layout with package responsibilities
  2. Dependency Flow: Diagram showing inward dependency rule (Transport → UseCase → Domain ← Repository)
  3. DI Container: Code showing explicit dependency injection wiring
  4. Patterns: Transaction management, outbox, CQRS where applicable
  5. Boundaries: Clear separation between layers and bounded contexts
  6. Examples: Concise code demonstrating architecture patterns (detailed examples in references/)
  7. Rationale: Justification for architectural choices (scalability, maintainability, testability)

Focus on practical, production-ready architecture patterns that balance complexity with maintainability.

Edge Cases

If architecture requirements are unclear or ambiguous: Ask clarifying questions about system boundaries, scalability needs, and domain complexity before proposing structure.

If domain complexity is unclear: Determine if bounded contexts are needed or if simple CRUD with clean architecture suffices.

If performance concerns arise: Delegate to go-perf skill for profiling, optimization strategies, and performance architecture decisions.

If code implementation patterns are needed: Delegate to go-code skill for specific implementation details and Go idioms.

If API design is required: Delegate to go-api skill for OpenAPI spec design and transport layer patterns.

If database patterns are needed: Delegate to go-db skill for repository implementation and database architecture.

If security architecture is relevant: Delegate to go-sec skill for authentication, authorization, and security layer design.

If testing strategy is needed: Delegate to go-test skill for test architecture and layer-specific testing approaches.

Examples

Example 1

Input: Design the layer structure for a user management service

Output:

code
internal/
├── domain/      # entity (no tags), contract (interfaces), event
├── usecase/     # CreateUser, GetUser
├── repository/  # user/pgx: repo, models, mappers, create
├── transport/   # http: handler, dto
└── app/         # app.go, di.go, uc.go

Pattern: Domain zero deps, repo implements contract, transport calls usecases.

Example 2

Input: Implement transaction management with outbox pattern for order creation

Output:

go
type createOrderUC struct {
    orderRepo contract.OrderRepo
    outbox    contract.OutboxRepo
    tx        TxManager
}

func (uc *createOrderUC) Execute(ctx context.Context, req CreateOrderReq) error {
    return uc.tx.WithTx(ctx, func(ctx context.Context) error {
        if err := uc.orderRepo.Save(ctx, order); err != nil {
            return fmt.Errorf("save order: %w", err)
        }
        event := OrderCreated{ID: order.ID, Items: req.Items}
        return uc.outbox.Save(ctx, &Outbox{
            Topic:   "orders.created",
            Payload: mustMarshal(event),
        })
    })
}

Pattern: Atomic transaction ensures order + outbox written together. Consumer reads outbox and publishes.

Example 3

Input: Design DI container for multiple bounded contexts

Output:

go
type container struct {
    infra  *infraDeps        // db, redis, mq
    users  *userContextDeps  // repo, create UC
    orders *orderContextDeps // repo, items, create UC
}

func newContainer(cfg *config.Config, log *slog.Logger) (*container, error) {
    c := &container{}
    c.infra = &infraDeps{db: newPool(cfg.DB), redis: newRedis(cfg), mq: newMQ(cfg)}
    c.users = &userContextDeps{repo: userRepo.New(c.infra.db), create: usecase.NewCreateUser(c.users.repo, log)}
    c.orders = &orderContextDeps{repo: orderRepo.New(c.infra.db), items: itemRepo.New(c.infra.db), create: usecase.NewCreateOrder(c.orders.repo, c.orders.items, log)}
    return c, nil
}

Pattern: Infra → repos → usecases, explicit dependency graph per bounded context.

Example 4

Input: Design CQRS pattern for order system with read/write separation

Output: For detailed implementation, see: references/cqrs-pattern.md

Pattern:

  • Command side: Write to event store via OrderCommandHandler
  • Query side: Read from denormalized OrderQueryModel via OrderQueryHandler
  • Projection: OrderProjector subscribes to events and updates read model

Use when: High read/write ratio, need independent scaling, or require full audit trail.

Example 5

Input: Design microservice architecture with bounded contexts and async communication

Output: For detailed implementation, see: references/microservice-architecture.md

Pattern:

code
services/
├── user-service/      # Bounded context
├── order-service/     # Bounded context
├── payment-service/   # Bounded context
└── notification-service/  # Bounded context
api-gateway/          # Single entry point, auth, routing

Communication: Async events via message queue (order-created → notification)

Use when: Multiple teams, independent deployment, or clear domain boundaries exist.

References