25 - Web 框架:Gin、Echo、Chi、路由、中间件
25 - Web 框架
25.1 Gin
Gin 是 Go 最流行的 Web 框架,性能优秀,API 简洁。
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default() // 带 Logger 和 Recovery 中间件
// 路由组
v1 := r.Group("/api/v1")
{
v1.GET("/users", listUsers)
v1.POST("/users", createUser)
v1.GET("/users/:id", getUser)
v1.PUT("/users/:id", updateUser)
v1.DELETE("/users/:id", deleteUser)
}
r.Run(":8080")
}
func listUsers(c *gin.Context) {
page := c.DefaultQuery("page", "1")
size := c.DefaultQuery("size", "10")
c.JSON(http.StatusOK, gin.H{
"page": page,
"size": size,
"users": []gin.H{},
})
}
func createUser(c *gin.Context) {
var req struct {
Name string `json:"name" binding:"required"`
Email string `json:"email" binding:"required,email"`
Age int `json:"age" binding:"gte=0,lte=150"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, gin.H{
"id": 1,
"name": req.Name,
"email": req.Email,
})
}
func getUser(c *gin.Context) {
id := c.Param("id")
c.JSON(http.StatusOK, gin.H{
"id": id,
"name": "Alice",
})
}
func updateUser(c *gin.Context) {
id := c.Param("id")
var req struct {
Name string `json:"name"`
}
c.ShouldBindJSON(&req)
c.JSON(http.StatusOK, gin.H{"id": id, "name": req.Name})
}
func deleteUser(c *gin.Context) {
id := c.Param("id")
c.JSON(http.StatusOK, gin.H{"message": "User " + id + " deleted"})
}
Gin 中间件
// 自定义中间件
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
// 验证 token...
c.Set("user_id", 123)
c.Next()
}
}
// 使用中间件
authorized := r.Group("/api", AuthMiddleware())
{
authorized.GET("/profile", getProfile)
}
Gin 响应工具
// 统一响应结构
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data any `json:"data,omitempty"`
}
func success(c *gin.Context, data any) {
c.JSON(http.StatusOK, Response{
Code: 0,
Message: "success",
Data: data,
})
}
func fail(c *gin.Context, code int, msg string) {
c.JSON(code, Response{
Code: code,
Message: msg,
})
}
25.2 Echo
import (
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
func main() {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.Use(middleware.CORS())
e.GET("/users", listUsers)
e.POST("/users", createUser)
e.GET("/users/:id", getUser)
e.Logger.Fatal(e.Start(":8080"))
}
func listUsers(c echo.Context) error {
page := c.QueryParam("page")
return c.JSON(200, map[string]any{
"page": page,
"users": []any{},
})
}
func createUser(c echo.Context) error {
var req struct {
Name string `json:"name"`
Email string `json:"email"`
}
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(400, err.Error())
}
return c.JSON(201, req)
}
func getUser(c echo.Context) error {
id := c.Param("id")
return c.JSON(200, map[string]string{"id": id, "name": "Alice"})
}
25.3 Chi
轻量级、兼容 net/http 的路由框架。
import (
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
func main() {
r := chi.NewRouter()
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Use(middleware.Timeout(60 * time.Second))
r.Route("/api", func(r chi.Router) {
r.Route("/users", func(r chi.Router) {
r.Get("/", listUsers)
r.Post("/", createUser)
r.Route("/{id}", func(r chi.Router) {
r.Get("/", getUser)
r.Put("/", updateUser)
r.Delete("/", deleteUser)
})
})
})
http.ListenAndServe(":8080", r)
}
func getUser(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
json.NewEncoder(w).Encode(map[string]string{"id": id, "name": "Alice"})
}
25.4 框架对比
| 特性 | Gin | Echo | Chi | net/http |
|---|---|---|---|---|
| 路由性能 | ⚡ 高 | ⚡ 高 | ⚡ 高 | 🟡 中 |
| API 风格 | 独特 | 独特 | 兼容 net/http | 原生 |
| 中间件 | ✅ | ✅ | ✅ | 需自己实现 |
| 学习曲线 | 低 | 低 | 低 | 低 |
| 生态系统 | 最丰富 | 丰富 | 中等 | 标准库 |
| 文档质量 | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ |
选择建议
- 快速开发:Gin(生态最丰富,文档最好)
- 兼容标准库:Chi(完全兼容 net/http handler)
- 极简风格:Echo(API 简洁清晰)
- 无依赖:net/http(Go 1.22+ 增强路由已够用)
25.5 项目结构示例
myproject/
├── main.go
├── cmd/
│ └── server/
│ └── main.go
├── internal/
│ ├── handler/ # HTTP 处理器
│ │ ├── user.go
│ │ └── user_test.go
│ ├── middleware/ # 中间件
│ │ ├── auth.go
│ │ └── logging.go
│ ├── model/ # 数据模型
│ │ └── user.go
│ ├── service/ # 业务逻辑
│ │ └── user.go
│ └── repository/ # 数据访问
│ └── user.go
├── config/
│ └── config.go
├── go.mod
└── go.sum
// 分层架构示例
// handler -> service -> repository
// handler/user.go
type UserHandler struct {
service *service.UserService
}
func (h *UserHandler) GetUser(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
user, err := h.service.GetByID(id)
if err != nil {
c.JSON(404, gin.H{"error": "User not found"})
return
}
c.JSON(200, user)
}
// service/user.go
type UserService struct {
repo repository.UserRepository
}
func (s *UserService) GetByID(id int) (*model.User, error) {
return s.repo.FindByID(id)
}
// repository/user.go
type UserRepository interface {
FindByID(id int) (*model.User, error)
Save(user *model.User) error
}
🏢 业务场景
- REST API 服务:Gin/Chi 构建用户、订单等 API
- 微服务网关:Chi 实现 API Gateway
- 管理后台:Gin + 模板渲染管理界面
- 原型开发:Gin 快速搭建 API 原型