Go语言网络编程 - 使用
net/http
构建 RESTful API 的内容。本章节将带你使用标准库构建一个简单清晰、符合 REST 风格的 API 接口服务。
一、什么是 RESTful API
REST(Representational State Transfer)是一种风格,通常遵循以下规范:
动作 | 方法 | 描述 |
获取资源 | GET | /users 、/users/1 |
创建资源 | POST | /users |
更新资源 | PUT | /users/1 |
删除资源 | DELETE | /users/1 |
二、准备数据结构和模拟数据库
package main import ( "encoding/json" "fmt" "log" "net/http" "strconv" "strings" "sync" ) type User struct { ID int `json:"id"` Name string `json:"name"` } var ( users = []User{} nextID = 1 userMux sync.Mutex )
三、实现核心的 HTTP 路由处理函数
1. 获取所有用户(GET /users)
func getUsers(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") userMux.Lock() defer userMux.Unlock() json.NewEncoder(w).Encode(users) }
2. 获取单个用户(GET /users/{id})
func getUser(w http.ResponseWriter, r *http.Request) { id := getIDFromPath(r.URL.Path) userMux.Lock() defer userMux.Unlock() for _, u := range users { if u.ID == id { json.NewEncoder(w).Encode(u) return } } http.NotFound(w, r) }
3. 创建用户(POST /users)
func createUser(w http.ResponseWriter, r *http.Request) { var u User if err := json.NewDecoder(r.Body).Decode(&u); err != nil { http.Error(w, "Invalid JSON", http.StatusBadRequest) return } userMux.Lock() u.ID = nextID nextID++ users = append(users, u) userMux.Unlock() w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(u) }
4. 更新用户(PUT /users/{id})
func updateUser(w http.ResponseWriter, r *http.Request) { id := getIDFromPath(r.URL.Path) var update User if err := json.NewDecoder(r.Body).Decode(&update); err != nil { http.Error(w, "Invalid JSON", http.StatusBadRequest) return } userMux.Lock() defer userMux.Unlock() for i, u := range users { if u.ID == id { users[i].Name = update.Name json.NewEncoder(w).Encode(users[i]) return } } http.NotFound(w, r) }
5. 删除用户(DELETE /users/{id})
func deleteUser(w http.ResponseWriter, r *http.Request) { id := getIDFromPath(r.URL.Path) userMux.Lock() defer userMux.Unlock() for i, u := range users { if u.ID == id { users = append(users[:i], users[i+1:]...) w.WriteHeader(http.StatusNoContent) return } } http.NotFound(w, r) }
四、辅助函数:路径中提取 ID
func getIDFromPath(path string) int { parts := strings.Split(path, "/") idStr := parts[len(parts)-1] id, _ := strconv.Atoi(idStr) return id }
五、设置路由器并启动服务
func main() { http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: getUsers(w, r) case http.MethodPost: createUser(w, r) default: http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) } }) http.HandleFunc("/users/", func(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: getUser(w, r) case http.MethodPut: updateUser(w, r) case http.MethodDelete: deleteUser(w, r) default: http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) } }) fmt.Println("Listening on :8080...") log.Fatal(http.ListenAndServe(":8080", nil)) }
六、测试示例(使用 curl 或 Postman)
# 创建用户 curl -X POST -d '{"name":"Alice"}' http://localhost:8080/users -H "Content-Type: application/json" # 获取所有用户 curl http://localhost:8080/users # 获取单个用户 curl http://localhost:8080/users/1 # 更新用户 curl -X PUT -d '{"name":"Bob"}' http://localhost:8080/users/1 -H "Content-Type: application/json" # 删除用户 curl -X DELETE http://localhost:8080/users/1
七、小结
本章展示了如何使用 Go 的标准库构建一套完整的 RESTful API 服务,包括:
- • 路由分发
- • JSON 编解码
- • 方法区分(GET/POST/PUT/DELETE)
- • 并发安全的数据结构管理
- • 简单的路径参数解析
如需更复杂的功能(如认证、中间件、自动路由注册),可引入第三方库如 Gin
、Echo
、Chi
等。