第 1 章 · Gin 入门与项目结构
本章目标:理解 Gin 高性能 HTTP 框架定位;在 ~/learn-go/api-go-demo 创建虚构练习项目 api-go-demo(模块 example.com/api-go-demo);编写最小可运行服务并访问 health 探活端点;能用对照表说明 Gin 与 fastapi-web svc-demo、flask-web api-demo、paas ch17 gin-shop 在路由、部署、校验、文档上的差异;掌握 Go 项目标准布局与 go run 开发流程。
学时建议:3~4 小时(含 1.5 小时跟练)
前置:完成 go-dev ch01~ch08(Go 语法、模块、包);建议 go-dev ch12(HTTP 标准库)。学过 fastapi-web ch01 或 flask-web ch01 更佳但非必须。
1.1 场景说明:为什么需要 api-go-demo?
你在 fastapi-web 中用 svc-demo 搭建了现代异步 API,在 flask-web 中用 api-demo 实现了轻量 REST。现在团队要在 K8s 集群中部署一套高 QPS 商品读 API,对外规划域名为虚构的 https://api.example.com(教学占位,非真实生产地址),项目代号 api-go-demo。
| 维度 | api-demo(Flask) | svc-demo(FastAPI) | api-go-demo(Gin) |
|---|---|---|---|
| 定位 | 轻量 REST + 少量页面 | 纯 API、微服务优先 | 高 QPS JSON API、单二进制 |
| 路由 | Blueprint @app.route | 装饰器 + APIRouter | r.GET / Group |
| 数据校验 | Marshmallow / 手写 | Pydantic v2 内置 | binding + validator(ch07) |
| API 文档 | Flask-RESTX / 手写 | /docs 自动生成 | swaggo(ch11) |
| 部署 | gunicorn + venv | uvicorn + venv | 单二进制 + Docker |
| 典型场景 | 内部 API、原型 | AI 网关、BFF | 高并发 Sidecar、边缘节点 |
说明:本章所有路径、域名、密钥均为教学虚构,不涉及任何真实公司仓库、内部配置或生产密钥。
学习路径(gin-web)
ch01 入门与结构 → ch02 路由与中间件 → ch03 配置 → ch04 GORM
↑ 你在这里
全站字段约定(后续章节统一,勿混用旧字段):
| 实体 | 关键字段 | 说明 |
|---|---|---|
| Product | slug、is_published、price | 价格 int64 分,不用 is_active |
| User | email、password_hash、role | bcrypt 哈希,role 为 user/admin |
1.2 三栈核心对照表
| 对比项 | Flask(api-demo) | FastAPI(svc-demo) | Gin(api-go-demo) |
|---|---|---|---|
| 哲学 | 微框架、按需扩展 | API 优先、类型驱动 | 极简路由 + 中间件链 |
| 启动命令 | flask run | uvicorn main:app --reload | go run ./cmd/server |
| 默认服务器 | Werkzeug(开发) | ASGI uvicorn | net/http 内置 |
| 请求体解析 | request.get_json() | 自动绑定 Pydantic | ShouldBindJSON |
| 响应格式 | jsonify() | return dict | c.JSON() |
| 交互文档 | 需 Swagger 扩展 | /docs 开箱即用 | swaggo 注解(ch11) |
| 性能取向 | 中等 | 高(异步 I/O) | 极高(编译型 + 低 GC) |
| 学习曲线 | 先小后大 | 需熟悉 async | 需熟悉 Go 与指针 |
何时选 Gin:需要单二进制部署、K8s 多副本水平扩展、与 Go 微服务栈统一、对延迟敏感的商品读 API。
何时仍选 FastAPI/Flask:团队以 Python 为主、需快速原型、已有成熟 Python 基建且 QPS 不高。
本课程采用 三项目对照:api-demo 学轻量 REST、svc-demo 学现代异步 API、api-go-demo 学 Go 高性能 API——便于你在真实选型时做理性权衡。
对照章节:
| 主题 | flask-web | fastapi-web | gin-web(本章) |
|---|---|---|---|
| 入门与环境 | ch01 | ch01 | ch01 |
| 项目结构 | ch01 应用工厂 | ch02 APIRouter | ch01 标准布局 |
| 探活端点 | /health | /health | /health |
1.3 环境准备
与 go-dev ch01 相同,在独立目录练习,勿与其他 Go 项目混用 go.mod。
1.3.1 检查 Go 版本
go version
# 期望 go1.22+ 或 go1.23+
| 工具 | 最低版本 | 用途 |
|---|---|---|
| Go | 1.22+ | 编译与模块 |
| curl | 任意 | 探活验证 |
| Git | 任意 | 版本管理(可选) |
Windows 用户请确认 go 在 PATH 中;若使用 WSL,建议在 WSL 内完成本章跟练以保持路径一致(~/learn-go)。
1.3.2 创建工作目录
mkdir -p ~/learn-go/api-go-demo
cd ~/learn-go/api-go-demo
Windows PowerShell 等价:
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\learn-go\api-go-demo"
Set-Location "$env:USERPROFILE\learn-go\api-go-demo"
下文路径统一写 ~/learn-go/api-go-demo;Windows 请自行映射到用户目录。
1.4 逐步创建项目(操作表)
按顺序执行,每步完成后打勾,避免跳步导致 go mod 路径错误。
| 步骤 | 操作 | 验证方式 | 预期结果 |
|---|---|---|---|
| 1 | go mod init example.com/api-go-demo | 出现 go.mod | module 名为 example.com/api-go-demo |
| 2 | go get github.com/gin-gonic/gin@v1.10.0 | go.mod 含 gin | 依赖锁定 v1.10.0 |
| 3 | 创建 cmd/server/main.go | 文件存在 | 含 package main |
| 4 | 编写 health 路由 | 代码无红色报错 | GET /health 处理函数 |
| 5 | go run ./cmd/server | 终端无 panic | 监听 :8080 |
| 6 | curl http://127.0.0.1:8080/health | HTTP 200 | {"status":"ok"} |
| 7 | 创建 .gitignore | 忽略二进制 | 含 /bin/、*.exe |
| 8 | 创建 README.md 一行说明 | 文档存在 | 写明项目代号与启动命令 |
模块路径:必须使用 example.com/api-go-demo,与 paas ch17 gin-shop 及后续章节 import 路径一致。
1.5 初始化 go.mod 与依赖
cd ~/learn-go/api-go-demo
go mod init example.com/api-go-demo
go get github.com/gin-gonic/gin@v1.10.0
go.mod 初始内容类似:
module example.com/api-go-demo
go 1.22
require github.com/gin-gonic/gin v1.10.0
| 包 | 作用 |
|---|---|
github.com/gin-gonic/gin | Web 框架,基于 net/http 封装路由与中间件 |
net/http | Go 标准库 HTTP 服务器(Gin 底层使用) |
安装完成后可用 go mod tidy 清理未使用依赖;后续章节会陆续加入 GORM、Viper、JWT 等。
1.6 最小 Gin 应用
1.6.1 第 1 章目录结构
api-go-demo/ # 仓库根(练习用)
├── cmd/
│ └── server/
│ └── main.go # 应用入口(本章单文件启动)
├── go.mod
├── go.sum
├── .gitignore
├── .env.example # 仅占位,ch03 详讲
└── README.md
与 fastapi-web ch01 的 main.py 单文件入口类似;ch02 起拆分为 internal/ 多包结构。
1.6.2 cmd/server/main.go 完整代码
// cmd/server/main.go
// api-go-demo 最小入口 — Gin 入门示例
package main
import (
"log"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"service": "api-go-demo",
"status": "ok",
})
})
r.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
})
})
r.GET("/api/v1/info", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"name": "api-go-demo",
"domain": "api.example.com",
"framework": "Gin",
"module": "example.com/api-go-demo",
})
})
if err := r.Run(":8080"); err != nil {
log.Fatal(err)
}
}
| 路由 | 方法 | 说明 |
|---|---|---|
/ | GET | 根路径,确认服务存活 |
/health | GET | 部署探活(与 Flask/FastAPI 对齐) |
/api/v1/info | GET | 元信息,供网关与前端发现 |
1.6.3 启动与验证
cd ~/learn-go/api-go-demo