feat(架构): 完善基础架构设计
This commit is contained in:
279
docs/开始指南/开发指南.md
Normal file
279
docs/开始指南/开发指南.md
Normal file
@@ -0,0 +1,279 @@
|
||||
# 👨💻 开发指南
|
||||
|
||||
## 项目结构理解
|
||||
|
||||
```
|
||||
tyapi-server-gin/
|
||||
├── cmd/api/ # 应用入口
|
||||
├── internal/ # 内部代码
|
||||
│ ├── app/ # 应用层
|
||||
│ ├── config/ # 配置管理
|
||||
│ ├── container/ # 依赖注入
|
||||
│ ├── domains/ # 业务域
|
||||
│ │ └── user/ # 用户域示例
|
||||
│ └── shared/ # 共享基础设施
|
||||
├── pkg/ # 外部包
|
||||
├── scripts/ # 脚本文件
|
||||
├── test/ # 测试文件
|
||||
└── docs/ # 文档目录
|
||||
```
|
||||
|
||||
## 开发流程
|
||||
|
||||
### 1. 创建新的业务域
|
||||
|
||||
```bash
|
||||
# 使用Makefile创建新域
|
||||
make new-domain DOMAIN=product
|
||||
|
||||
# 手动创建目录结构
|
||||
mkdir -p internal/domains/product/{entities,dto,services,repositories,handlers,routes,events}
|
||||
```
|
||||
|
||||
### 2. 实现业务实体
|
||||
|
||||
创建 `internal/domains/product/entities/product.go`:
|
||||
|
||||
```go
|
||||
type Product struct {
|
||||
BaseEntity
|
||||
Name string `gorm:"not null;size:100"`
|
||||
Description string `gorm:"size:500"`
|
||||
Price float64 `gorm:"not null"`
|
||||
CategoryID uint `gorm:"not null"`
|
||||
}
|
||||
|
||||
func (p *Product) Validate() error {
|
||||
if p.Name == "" {
|
||||
return errors.New("产品名称不能为空")
|
||||
}
|
||||
if p.Price <= 0 {
|
||||
return errors.New("产品价格必须大于0")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 定义仓储接口
|
||||
|
||||
创建 `internal/domains/product/repositories/product_repository.go`:
|
||||
|
||||
```go
|
||||
type ProductRepository interface {
|
||||
shared.BaseRepository[entities.Product]
|
||||
FindByCategory(ctx context.Context, categoryID uint) ([]*entities.Product, error)
|
||||
FindByPriceRange(ctx context.Context, min, max float64) ([]*entities.Product, error)
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 实现业务服务
|
||||
|
||||
创建 `internal/domains/product/services/product_service.go`:
|
||||
|
||||
```go
|
||||
type ProductService interface {
|
||||
CreateProduct(ctx context.Context, req *dto.CreateProductRequest) (*dto.ProductResponse, error)
|
||||
GetProduct(ctx context.Context, id uint) (*dto.ProductResponse, error)
|
||||
UpdateProduct(ctx context.Context, id uint, req *dto.UpdateProductRequest) (*dto.ProductResponse, error)
|
||||
DeleteProduct(ctx context.Context, id uint) error
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 实现 HTTP 处理器
|
||||
|
||||
创建 `internal/domains/product/handlers/product_handler.go`:
|
||||
|
||||
```go
|
||||
func (h *ProductHandler) CreateProduct(c *gin.Context) {
|
||||
var req dto.CreateProductRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "请求参数无效", err)
|
||||
return
|
||||
}
|
||||
|
||||
product, err := h.productService.CreateProduct(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "创建产品失败", err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, product)
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 配置路由
|
||||
|
||||
创建 `internal/domains/product/routes/product_routes.go`:
|
||||
|
||||
```go
|
||||
func RegisterProductRoutes(router shared.Router, handler *handlers.ProductHandler) {
|
||||
v1 := router.Group("/api/v1")
|
||||
{
|
||||
products := v1.Group("/products")
|
||||
{
|
||||
products.POST("", handler.CreateProduct)
|
||||
products.GET("/:id", handler.GetProduct)
|
||||
products.PUT("/:id", handler.UpdateProduct)
|
||||
products.DELETE("/:id", handler.DeleteProduct)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 常用开发命令
|
||||
|
||||
```bash
|
||||
# 代码格式化
|
||||
make fmt
|
||||
|
||||
# 代码检查
|
||||
make lint
|
||||
|
||||
# 运行测试
|
||||
make test
|
||||
|
||||
# 测试覆盖率
|
||||
make test-coverage
|
||||
|
||||
# 生成API文档
|
||||
make docs
|
||||
|
||||
# 热重载开发
|
||||
make dev
|
||||
|
||||
# 构建二进制文件
|
||||
make build
|
||||
|
||||
# 清理临时文件
|
||||
make clean
|
||||
```
|
||||
|
||||
## 测试编写
|
||||
|
||||
### 单元测试示例
|
||||
|
||||
```go
|
||||
func TestProductService_CreateProduct(t *testing.T) {
|
||||
// 设置测试数据
|
||||
mockRepo := mocks.NewProductRepository(t)
|
||||
service := services.NewProductService(mockRepo, nil)
|
||||
|
||||
req := &dto.CreateProductRequest{
|
||||
Name: "测试产品",
|
||||
Description: "测试描述",
|
||||
Price: 99.99,
|
||||
CategoryID: 1,
|
||||
}
|
||||
|
||||
// 设置Mock期望
|
||||
mockRepo.On("Create", mock.Anything, mock.AnythingOfType("*entities.Product")).
|
||||
Return(&entities.Product{}, nil)
|
||||
|
||||
// 执行测试
|
||||
result, err := service.CreateProduct(context.Background(), req)
|
||||
|
||||
// 断言结果
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, result)
|
||||
assert.Equal(t, req.Name, result.Name)
|
||||
}
|
||||
```
|
||||
|
||||
### 集成测试示例
|
||||
|
||||
```go
|
||||
func TestProductAPI_Integration(t *testing.T) {
|
||||
// 启动测试服务器
|
||||
testApp := setupTestApp(t)
|
||||
defer testApp.Cleanup()
|
||||
|
||||
// 创建测试请求
|
||||
reqBody := `{"name":"测试产品","price":99.99,"category_id":1}`
|
||||
req := httptest.NewRequest("POST", "/api/v1/products", strings.NewReader(reqBody))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// 执行请求
|
||||
w := httptest.NewRecorder()
|
||||
testApp.ServeHTTP(w, req)
|
||||
|
||||
// 验证响应
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
|
||||
var response map[string]interface{}
|
||||
json.Unmarshal(w.Body.Bytes(), &response)
|
||||
assert.Equal(t, "success", response["status"])
|
||||
}
|
||||
```
|
||||
|
||||
## 开发规范
|
||||
|
||||
### 代码风格
|
||||
|
||||
- 使用 `gofmt` 格式化代码
|
||||
- 遵循 Go 命名规范
|
||||
- 添加必要的注释和文档
|
||||
- 函数长度不超过 50 行
|
||||
|
||||
### Git 提交规范
|
||||
|
||||
```bash
|
||||
# 功能开发
|
||||
git commit -m "feat: 添加用户注册功能"
|
||||
|
||||
# 问题修复
|
||||
git commit -m "fix: 修复登录验证问题"
|
||||
|
||||
# 文档更新
|
||||
git commit -m "docs: 更新API文档"
|
||||
|
||||
# 重构代码
|
||||
git commit -m "refactor: 重构用户服务层"
|
||||
```
|
||||
|
||||
### 分支管理
|
||||
|
||||
- `main`: 主分支,用于生产发布
|
||||
- `develop`: 开发分支,用于集成测试
|
||||
- `feature/xxx`: 功能分支,用于新功能开发
|
||||
- `hotfix/xxx`: 热修复分支,用于紧急修复
|
||||
|
||||
## 调试技巧
|
||||
|
||||
### 使用 Delve 调试器
|
||||
|
||||
```bash
|
||||
# 安装 Delve
|
||||
go install github.com/go-delve/delve/cmd/dlv@latest
|
||||
|
||||
# 启动调试
|
||||
dlv debug ./cmd/api/main.go
|
||||
|
||||
# 设置断点
|
||||
(dlv) break main.main
|
||||
(dlv) continue
|
||||
```
|
||||
|
||||
### 日志调试
|
||||
|
||||
```go
|
||||
// 添加调试日志
|
||||
logger.Debug("Processing user request",
|
||||
zap.String("user_id", userID),
|
||||
zap.String("action", "create_product"))
|
||||
|
||||
// 临时调试信息
|
||||
fmt.Printf("Debug: %+v\n", debugData)
|
||||
```
|
||||
|
||||
### 性能分析
|
||||
|
||||
```bash
|
||||
# 启用 pprof
|
||||
go tool pprof http://localhost:8080/debug/pprof/profile
|
||||
|
||||
# 内存分析
|
||||
go tool pprof http://localhost:8080/debug/pprof/heap
|
||||
|
||||
# 协程分析
|
||||
go tool pprof http://localhost:8080/debug/pprof/goroutine
|
||||
```
|
||||
Reference in New Issue
Block a user