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 |
二、准备数据结构和模拟数据库
go
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)
scss
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})
scss
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)
scss
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})
go
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})
scss
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
go
func getIDFromPath(path string) int {
parts := strings.Split(path, "/")
idStr := parts[len(parts)-1]
id, _ := strconv.Atoi(idStr)
return id
}
五、设置路由器并启动服务
go
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)
bash
# 创建用户
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
等。