# 第四阶段:完整项目实践 - RESTful API服务 ## 学习目标 - 掌握完整的Web应用开发流程 - 理解RESTful API设计原则 - 能够构建生产级别的Go应用 - 掌握部署和运维技能 ## 项目需求分析 ### 用户管理系统功能 - 用户注册、登录、注销 - 用户信息管理(增删改查) - 权限控制与认证 - 数据验证与错误处理 - 日志记录与监控 ## 技术栈选择 ### 核心框架 - **Web框架**: Gin/Echo (推荐Gin) - **数据库**: MySQL/PostgreSQL - **ORM**: GORM - **认证**: JWT - **配置管理**: Viper - **日志**: Zap ### 开发工具 - **测试**: Go test + testify - **文档**: Swagger - **部署**: Docker - **监控**: Prometheus + Grafana ## 项目架构设计 ### 目录结构 ``` user-management/ ├── cmd/ │ └── server/ │ └── main.go # 应用入口 ├── internal/ │ ├── config/ # 配置管理 │ ├── handler/ # HTTP处理器 │ ├── middleware/ # 中间件 │ ├── model/ # 数据模型 │ ├── repository/ # 数据访问层 │ ├── service/ # 业务逻辑层 │ └── utils/ # 工具函数 ├── pkg/ │ ├── auth/ # 认证模块 │ ├── database/ # 数据库连接 │ └── logger/ # 日志模块 ├── api/ │ └── docs/ # API文档 ├── scripts/ # 部署脚本 ├── docker-compose.yml # Docker配置 ├── go.mod # 依赖管理 └── README.md # 项目说明 ``` ## 核心代码实现 ### 1. 配置管理 (config/config.go) ```go package config type Config struct { Server ServerConfig `mapstructure:"server"` Database DatabaseConfig `mapstructure:"database"` JWT JWTConfig `mapstructure:"jwt"` } type ServerConfig struct { Port string `mapstructure:"port"` Mode string `mapstructure:"mode"` } type DatabaseConfig struct { Host string `mapstructure:"host"` Port string `mapstructure:"port"` User string `mapstructure:"user"` Password string `mapstructure:"password"` DBName string `mapstructure:"dbname"` } type JWTConfig struct { Secret string `mapstructure:"secret"` Expire int `mapstructure:"expire"` } func Load() (*Config, error) { // 实现配置加载逻辑 } ``` ### 2. 数据模型 (model/user.go) ```go package model import "time" type User struct { ID uint `gorm:"primaryKey" json:"id"` Username string `gorm:"uniqueIndex;not null" json:"username"` Email string `gorm:"uniqueIndex;not null" json:"email"` Password string `gorm:"not null" json:"-"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } type CreateUserRequest struct { Username string `json:"username" binding:"required,min=3,max=50"` Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required,min=6"` } type LoginRequest struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required"` } type UserResponse struct { ID uint `json:"id"` Username string `json:"username"` Email string `json:"email"` } ``` ### 3. 业务逻辑层 (service/user_service.go) ```go package service import ( "user-management/internal/model" "user-management/internal/repository" "golang.org/x/crypto/bcrypt" ) type UserService struct { userRepo repository.UserRepository } func NewUserService(repo repository.UserRepository) *UserService { return &UserService{userRepo: repo} } func (s *UserService) CreateUser(req model.CreateUserRequest) (*model.UserResponse, error) { // 密码加密 hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) if err != nil { return nil, err } user := &model.User{ Username: req.Username, Email: req.Email, Password: string(hashedPassword), } if err := s.userRepo.Create(user); err != nil { return nil, err } return &model.UserResponse{ ID: user.ID, Username: user.Username, Email: user.Email, }, nil } func (s *UserService) Authenticate(req model.LoginRequest) (*model.User, error) { user, err := s.userRepo.FindByUsername(req.Username) if err != nil { return nil, err } if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil { return nil, err } return user, nil } ``` ### 4. HTTP处理器 (handler/user_handler.go) ```go package handler import ( "net/http" "user-management/internal/model" "user-management/internal/service" "github.com/gin-gonic/gin" ) type UserHandler struct { userService *service.UserService authService *service.AuthService } func NewUserHandler(userService *service.UserService, authService *service.AuthService) *UserHandler { return &UserHandler{ userService: userService, authService: authService, } } // Register 用户注册 // @Summary 用户注册 // @Tags users // @Accept json // @Produce json // @Param user body model.CreateUserRequest true "用户信息" // @Success 201 {object} model.UserResponse // @Router /api/v1/register [post] func (h *UserHandler) Register(c *gin.Context) { var req model.CreateUserRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } user, err := h.userService.CreateUser(req) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, user) } // Login 用户登录 // @Summary 用户登录 // @Tags users // @Accept json // @Produce json // @Param credentials body model.LoginRequest true "登录凭证" // @Success 200 {object} gin.H // @Router /api/v1/login [post] func (h *UserHandler) Login(c *gin.Context) { var req model.LoginRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } user, err := h.userService.Authenticate(req) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "用户名或密码错误"}) return } token, err := h.authService.GenerateToken(user.ID) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{ "token": token, "user": model.UserResponse{ ID: user.ID, Username: user.Username, Email: user.Email, }, }) } ``` ### 5. 中间件 (middleware/auth.go) ```go package middleware import ( "net/http" "strings" "user-management/pkg/auth" "github.com/gin-gonic/gin" ) func AuthMiddleware(jwtService *auth.JWTService) gin.HandlerFunc { return func(c *gin.Context) { authHeader := c.GetHeader("Authorization") if authHeader == "" { c.JSON(http.StatusUnauthorized, gin.H{"error": "缺少认证令牌"}) c.Abort() return } parts := strings.Split(authHeader, " ") if len(parts) != 2 || parts[0] != "Bearer" { c.JSON(http.StatusUnauthorized, gin.H{"error": "令牌格式错误"}) c.Abort() return } token := parts[1] claims, err := jwtService.ValidateToken(token) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "无效令牌"}) c.Abort() return } c.Set("userID", claims.UserID) c.Next() } } ``` ## API接口设计 ### 用户管理接口 | 方法 | 路径 | 描述 | 认证 | |------|------|------|------| | POST | /api/v1/register | 用户注册 | 否 | | POST | /api/v1/login | 用户登录 | 否 | | GET | /api/v1/users | 获取用户列表 | 是 | | GET | /api/v1/users/:id | 获取用户详情 | 是 | | PUT | /api/v1/users/:id | 更新用户信息 | 是 | | DELETE | /api/v1/users/:id | 删除用户 | 是 | ## 部署配置 ### Docker配置 (docker-compose.yml) ```yaml version: '3.8' services: app: build: . ports: - "8080:8080" environment: - DB_HOST=db - DB_PORT=3306 - DB_USER=user - DB_PASSWORD=password - DB_NAME=user_management depends_on: - db db: image: mysql:8.0 environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=user_management - MYSQL_USER=user - MYSQL_PASSWORD=password ports: - "3306:3306" volumes: - db_data:/var/lib/mysql volumes: db_data: ``` ## 测试策略 ### 单元测试 ```go func TestUserService_CreateUser(t *testing.T) { // 测试用户创建逻辑 } func TestUserService_Authenticate(t *testing.T) { // 测试用户认证逻辑 } ``` ### 集成测试 ```go func TestUserAPI(t *testing.T) { // 测试完整的API流程 } ``` ### 性能测试 ```go func BenchmarkUserCreation(b *testing.B) { // 性能基准测试 } ``` ## 评估标准 ### 功能完整性 (40%) - 所有API接口正常工作 - 错误处理完整 - 数据验证有效 ### 代码质量 (30%) - 代码结构清晰 - 遵循Go最佳实践 - 测试覆盖率达标 ### 性能与安全 (20%) - 响应时间合理 - 安全措施到位 - 资源使用优化 ### 文档与部署 (10%) - API文档完整 - 部署流程顺畅 - 监控配置完善 ## 时间安排 (4-5周) ### 第1周:项目搭建与基础功能 - 项目结构设计 - 数据库设计 - 基础CRUD功能 ### 第2周:认证与权限 - JWT认证实现 - 权限控制 - 中间件开发 ### 第3周:高级功能 - 数据验证 - 错误处理 - 日志记录 ### 第4周:测试与优化 - 单元测试 - 性能优化 - 安全加固 ### 第5周:部署与文档 - Docker部署 - API文档 - 监控配置 ## 项目成果 完成本项目后,您将拥有: 1. 一个完整的RESTful API服务 2. 生产级别的Go应用开发经验 3. 完整的开发-测试-部署流程 4. 可复用的项目模板 这个项目将为您后续的Go开发工作奠定坚实的基础!