引言:为什么用Go开发REST API?
\nGo(Golang)是一种现代编译型语言,内置并发支持且性能卓越。用Go开发的REST API运行速度快、内存占用少,且易于扩展。在30分钟内,您将使用标准库创建一个完整的REST服务,支持GET、POST、PUT和DELETE请求。
\n在本指南中,我们将编写一个用于管理任务列表(Todo应用)的API。您将学习如何配置路由、处理JSON、添加日志中间件以及正确返回错误。无需第三方框架——仅使用纯Go!
\n\n1. 项目设置与结构
\n为项目创建一个新目录并初始化Go模块:
\nmkdir go-todo-api\ncd go-todo-api\ngo mod init todo-api\n项目结构将非常简单:
\n- \n
main.go— 入口点和服务器启动 \nhandlers.go— 请求处理程序 \nmodels.go— 数据结构 \nmiddleware.go— 中间件 \n
创建包含任务结构的models.go文件:
package main\n\ntype Task struct {\n ID int `json:"id"`\n Title string `json:"title"`\n Completed bool `json:"completed"`\n}\n为简单起见,我们将任务存储在内存中(tasks切片)。在实际项目中,请使用数据库。
\n\n2. 路由与处理程序
\nGo使用内置的net/http包。创建包含主要处理程序的handlers.go文件。
2.1. GET /tasks — 获取所有任务
\npackage main\n\nimport (\n "encoding/json"\n "net/http"\n "strconv"\n)\n\nvar tasks = []Task{}\nvar nextID = 1\n\nfunc getTasks(w http.ResponseWriter, r *http.Request) {\n w.Header().Set("Content-Type", "application/json")\n json.NewEncoder(w).Encode(tasks)\n}\n2.2. POST /tasks — 创建新任务
\nfunc createTask(w http.ResponseWriter, r *http.Request) {\n var newTask Task\n if err := json.NewDecoder(r.Body).Decode(&newTask); err != nil {\n http.Error(w, "Invalid JSON", http.StatusBadRequest)\n return\n }\n newTask.ID = nextID\n nextID++\n tasks = append(tasks, newTask)\n w.Header().Set("Content-Type", "application/json")\n w.WriteHeader(http.StatusCreated)\n json.NewEncoder(w).Encode(newTask)\n}\n2.3. PUT /tasks/{id} — 更新任务
\nfunc updateTask(w http.ResponseWriter, r *http.Request) {\n idStr := r.PathValue("id")\n id, err := strconv.Atoi(idStr)\n if err != nil {\n http.Error(w, "Invalid task ID", http.StatusBadRequest)\n return\n }\n \n var updatedTask Task\n if err := json.NewDecoder(r.Body).Decode(&updatedTask); err != nil {\n http.Error(w, "Invalid JSON", http.StatusBadRequest)\n return\n }\n \n for i, t := range tasks {\n if t.ID == id {\n tasks[i].Title = updatedTask.Title\n tasks[i].Completed = updatedTask.Completed\n w.Header().Set("Content-Type", "application/json")\n json.NewEncoder(w).Encode(tasks[i])\n return\n }\n }\n http.Error(w, "Task not found", http.StatusNotFound)\n}\n2.4. DELETE /tasks/{id} — 删除任务
\nfunc deleteTask(w http.ResponseWriter, r *http.Request) {\n idStr := r.PathValue("id")\n id, err := strconv.Atoi(idStr)\n if err != nil {\n http.Error(w, "Invalid task ID", http.StatusBadRequest)\n return\n }\n \n for i, t := range tasks {\n if t.ID == id {\n tasks = append(tasks[:i], tasks[i+1:]...)\n w.WriteHeader(http.StatusNoContent)\n return\n }\n }\n http.Error(w, "Task not found", http.StatusNotFound)\n}\n请注意