文档
Gin RESTful API — 任务管理 Todo
目标
使用 Gin 框架快速搭建 Todo 任务 CRUD API,演示路由分组、参数绑定、中间件。
完整代码
package main
import (
"net/http"
"strconv"
"sync"
"time"
"github.com/gin-gonic/gin"
)
// Todo 模型
type Todo struct {
ID int `json:"id"`
Title string `json:"title" binding:"required"`
Completed bool `json:"completed"`
CreatedAt time.Time `json:"createdAt"`
}
var (
todos = []Todo{}
nextID = 1
mu sync.Mutex
)
func main() {
r := gin.Default()
// 分组路由
v1 := r.Group("/api/v1")
{
v1.GET("/todos", getTodos)
v1.GET("/todos/:id", getTodo)
v1.POST("/todos", createTodo)
v1.PUT("/todos/:id", updateTodo)
v1.DELETE("/todos/:id", deleteTodo)
}
r.Run(":8080")
}
func getTodos(c *gin.Context) {
mu.Lock()
defer mu.Unlock()
c.JSON(http.StatusOK, gin.H{"count": len(todos), "data": todos})
}
func getTodo(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
mu.Lock()
defer mu.Unlock()
for _, t := range todos {
if t.ID == id {
c.JSON(http.StatusOK, t)
return
}
}
c.JSON(http.StatusNotFound, gin.H{"error": "任务不存在"})
}
func createTodo(c *gin.Context) {
var todo Todo
if err := c.ShouldBindJSON(&todo); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
mu.Lock()
todo.ID = nextID
nextID++
todo.CreatedAt = time.Now()
todos = append(todos, todo)
mu.Unlock()
c.JSON(http.StatusCreated, todo)
}
func updateTodo(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
var input Todo
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
mu.Lock()
defer mu.Unlock()
for i, t := range todos {
if t.ID == id {
todos[i].Title = input.Title
todos[i].Completed = input.Completed
c.JSON(http.StatusOK, todos[i])
return
}
}
c.JSON(http.StatusNotFound, gin.H{"error": "任务不存在"})
}
func deleteTodo(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
mu.Lock()
defer mu.Unlock()
for i, t := range todos {
if t.ID == id {
todos = append(todos[:i], todos[i+1:]...)
c.JSON(http.StatusOK, gin.H{"message": "已删除"})
return
}
}
c.JSON(http.StatusNotFound, gin.H{"error": "任务不存在"})
}
运行步骤
go mod init todo-gin
go get github.com/gin-gonic/gin
go run main.go
测试
# 新增任务
curl -X POST http://localhost:8080/api/v1/todos \
-H "Content-Type: application/json" \
-d '{"title":"完成毕设论文"}'
# 获取全部
curl http://localhost:8080/api/v1/todos
# 更新为已完成
curl -X PUT http://localhost:8080/api/v1/todos/1 \
-H "Content-Type: application/json" \
-d '{"title":"完成毕设论文","completed":true}'
# 删除
curl -X DELETE http://localhost:8080/api/v1/todos/1
预期输出
- Gin 启动打印路由表,每个请求自动输出彩色日志
- JSON 绑定
binding:"required"自动校验,缺失 title 返回 400 - 并发安全:
sync.Mutex保护共享切片