4. 项目结构优化
优化总结
- 中间件处理(日志记录)
- 统一的响应处理
- API 文档
- 单元测试
- 更规范的错误处理
当前目录结构
当前项目采用了典型的 Go 项目分层架构,目录结构如下:
d:\works\RD\todo-list\
├── config\ # 配置相关
│ └── database.go # 数据库配置和初始化
├── controllers\ # 控制器层,处理HTTP请求
│ └── todo_controller.go # 待办事项的控制器
├── models\ # 数据模型层
│ └── todo.go # 待办事项的数据模型定义
├── routes\ # 路由层
│ └── routes.go # 路由配置和初始化
├── services\ # 服务层(当前为空,可以添加业务逻辑)
├── main.go # 程序入口文件
├── go.mod # Go模块定义
└── go.sum # 依赖版本锁定文件各层职责说明:
config: 负责配置管理,目前包含数据库配置controllers: 处理 HTTP 请求,实现接口逻辑models: 定义数据结构和数据库模型routes: 配置 API 路由services: 可以添加复杂的业务逻辑处理(当前未使用)
这种分层架构的优点:
- 职责分明,代码结构清晰
- 便于维护和扩展
- 符合单一职责原则
- 有利于团队协作
建议后续可以添加:
middleware目录:用于存放中间件utils目录:存放工具函数docs目录:存放 API 文档tests目录:存放测试文件
优化一波
给 AI 提问: 添加
middleware目录:用于存放中间件,utils目录:存放工具函数,docs目录:存放 API 文档,tests目录:存放测试文件,如何优化目录结构?
我来帮你优化项目结构。首先创建新的目录:
bash
mkdir d:\works\RD\todo-list\middleware
mkdir d:\works\RD\todo-list\utils
mkdir d:\works\RD\todo-list\docs
mkdir d:\works\RD\todo-list\tests- 首先创建一个日志中间件:
go
// :d:\works\RD\todo-list\middleware\logger.go
package middleware
import (
"github.com/gin-gonic/gin"
"time"
)
func Logger() gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
path := c.Request.URL.Path
c.Next()
latency := time.Since(start)
statusCode := c.Writer.Status()
gin.DefaultWriter.Write([]byte(
"[GIN] " + time.Now().Format("2006-01-02 15:04:05") +
" | " + c.Request.Method +
" | " + path +
" | " + string(rune(statusCode)) +
" | " + latency.String() + "\n",
))
}
}- 添加一个工具函数文件:
go
// :d:\works\RD\todo-list\utils\response.go
package utils
import "github.com/gin-gonic/gin"
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
}
func SuccessResponse(c *gin.Context, data interface{}) {
c.JSON(200, Response{
Code: 200,
Message: "success",
Data: data,
})
}
func ErrorResponse(c *gin.Context, code int, message string) {
c.JSON(code, Response{
Code: code,
Message: message,
Data: nil,
})
}- 添加测试文件示例:
go:d:\works\RD\todo-list\tests\todo_test.go
package tests
import (
"testing"
"net/http"
"net/http/httptest"
"todo-list/routes"
)
func TestGetTodos(t *testing.T) {
router := routes.SetupRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/api/v1/todos", nil)
router.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("Expected status 200, got %v", w.Code)
}
}- 添加 API 文档:
markdown
<!-- :d:\works\RD\todo-list\docs\api.md -->
# Todo List API 文档
## 接口列表
### 1. 创建待办事项
- 请求方法:POST
- 路径:/api/v1/todos
- 请求体:
```json
{
"title": "任务标题",
"description": "任务描述",
"due_date": "2024-05-13T00:00:00Z",
"completed": false
}
```
### 2. 获取所有待办事项
- 请求方法:GET
- 路径:/api/v1/todos
### 3. 获取单个待办事项
- 请求方法:GET
- 路径:/api/v1/todos/:id
### 4. 更新待办事项
- 请求方法:PUT
- 路径:/api/v1/todos/:id
### 5. 删除待办事项
- 请求方法:DELETE
- 路径:/api/v1/todos/:id- 更新路由文件以使用中间件:
go
// :d:\works\RD\todo-list\routes\routes.go
package routes
import (
"github.com/gin-gonic/gin"
"todo-list/controllers"
"todo-list/config"
"todo-list/middleware"
)
func SetupRouter() *gin.Engine {
r := gin.Default()
// 使用自定义中间件
r.Use(middleware.Logger())
// 获取数据库实例
db, _ := config.InitDB()
todoController := controllers.NewTodoController(db)
// 设置路由
v1 := r.Group("/api/v1")
{
todos := v1.Group("/todos")
{
todos.POST("/", todoController.Create)
todos.GET("/", todoController.GetAll)
todos.GET("/:id", todoController.GetOne)
todos.PUT("/:id", todoController.Update)
todos.DELETE("/:id", todoController.Delete)
}
}
return r
}- 更新控制器以使用统一响应格式:
go
// :d:\works\RD\todo-list\controllers\todo_controller.go
// 修改 Create 方法示例
func (tc *TodoController) Create(c *gin.Context) {
var todo models.Todo
if err := c.ShouldBindJSON(&todo); err != nil {
utils.ErrorResponse(c, http.StatusBadRequest, err.Error())
return
}
if err := tc.DB.Create(&todo).Error; err != nil {
utils.ErrorResponse(c, http.StatusInternalServerError, "创建待办事项失败")
return
}
utils.SuccessResponse(c, todo)
}这样的目录结构更加完整,包含了:
- 中间件处理(日志记录)
- 统一的响应处理
- API 文档
- 单元测试
- 更规范的错误处理
建议后续可以继续添加:
- 配置文件管理(如 config.yaml)
- 更多中间件(如认证、跨域处理等)
- 更完善的日志系统
- 更多单元测试用例