Gin 毕设实战 — Go Web 开发从入门到上线

知识库
知识库文档
/tech-stacks/gin/tutorial/Gin 毕设实战 — Go Web 开发从入门到上线.md

文档

Gin 毕设实战 — Go Web 开发从入门到上线

前言

Gin 是国内 Go 后端开发的事实标准。它性能极高、API 简洁,非常适合毕设中需要高性能接口的场景(如数据处理、实时计算)。

第一章:Gin 的 radix tree 路由

Gin 基于 httprouter 的压缩前缀树(radix tree),路由时间复杂度 O(log n):

GET /api/users
GET /api/users/:id
GET /api/users/:id/posts
POST /api/users
POST /api/posts

这些路由被组织成一棵树,查找效率极高。相比之下 Express 对每个路由遍历正则匹配。

第二章:请求验证

Gin 使用 validator 库做 struct tag 验证:

type CreateOrderReq struct {
    UserID    int     `json:"userId" binding:"required,min=1"`
    ProductID int     `json:"productId" binding:"required"`
    Quantity  int     `json:"quantity" binding:"required,min=1,max=100"`
    Coupon    string  `json:"coupon" binding:"omitempty,len=6"`
    Email     string  `json:"email" binding:"required,email"`
}

func createOrder(c *gin.Context) {
    var req CreateOrderReq
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }
    // 验证通过,req 可直接使用
}

常用验证标签:requiredminmaxlenemailurloneofgtelte

第三章:中间件开发

// 自定义 JWT 中间件
func AuthMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        token := c.GetHeader("Authorization")
        if token == "" || !strings.HasPrefix(token, "Bearer ") {
            c.AbortWithStatusJSON(401, gin.H{"error": "未登录"})
            return
        }
        claims, err := parseToken(token[7:])
        if err != nil {
            c.AbortWithStatusJSON(401, gin.H{"error": "Token 无效"})
            return
        }
        c.Set("userId", claims.UserID) // 存入上下文
        c.Next()
    }
}

// 使用
r.Group("/api").Use(AuthMiddleware())
{
    // 此组内所有路由都需认证
}

第四章:使用 GORM 操作数据库

// 模型定义
type Article struct {
    ID        uint   `gorm:"primaryKey"`
    Title     string `gorm:"size:200;not null"`
    Content   string `gorm:"type:text"`
    UserID    uint
    CreatedAt time.Time
}

// 初始化
db, _ := gorm.Open(sqlite.Open("blog.db"), &gorm.Config{})
db.AutoMigrate(&Article{})

// 在 Handler 中使用
func listArticles(c *gin.Context) {
    var articles []Article
    db.Find(&articles)
    c.JSON(200, articles)
}

第五章:优雅关停

srv := &http.Server{Addr: ":8080", Handler: r}

go func() {
    if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        log.Fatal(err)
    }
}()

// 等待中断信号
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down...")

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Shutdown(ctx) // 等待进行中的请求完成

思考题

  1. Gin 的 ShouldBindJSONMustBindJSON 区别是什么?
  2. 如何在 Gin 中实现请求限流(rate limiting)?
  3. Go 的 context.Context 在 Web 请求中有什么作用?

信息

路径
/tech-stacks/gin/tutorial/Gin 毕设实战 — Go Web 开发从入门到上线.md
更新时间
2026/5/30