phase4-project.md 10 KB

第四阶段:完整项目实践 - 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)

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)

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)

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)

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)

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)

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:

测试策略

单元测试

func TestUserService_CreateUser(t *testing.T) {
    // 测试用户创建逻辑
}

func TestUserService_Authenticate(t *testing.T) {
    // 测试用户认证逻辑
}

集成测试

func TestUserAPI(t *testing.T) {
    // 测试完整的API流程
}

性能测试

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开发工作奠定坚实的基础!