RESTful风格API设计
RESTful 是 Web API 设计的推荐风格,强调资源导向和统一接口。
RESTful 核心原则
| 原则 | 说明 |
|---|---|
| 资源导向 | URL 表示资源,而非动作 |
| HTTP 方法语义 | 使用标准方法表示操作 |
| 无状态 | 每次请求包含完整信息 |
| 统一接口 | 一致的 URL 和响应格式 |
HTTP 方法语义
| 方法 | 语义 | URL 示例 |
|---|---|---|
| GET | 获取资源 | /users 或 /users/:id |
| POST | 创建资源 | /users |
| PUT | 更新资源(全量) | /users/:id |
| PATCH | 更新资源(部分) | /users/:id |
| DELETE | 删除资源 | /users/:id |
资源命名规范
Go
// ✅ 推荐:资源名词,复数表示集合
r.GET("/users", listUsers) // 用户列表
r.GET("/users/:id", getUser) // 单个用户
r.POST("/users", createUser) // 创建用户
r.PUT("/users/:id", updateUser) // 更新用户
r.DELETE("/users/:id", deleteUser) // 删除用户
// ❌ 不推荐:动词在 URL 中
r.GET("/getUser", ...) // 动词不应出现在 URL
r.POST("/createUser", ...)
完整 RESTful 示例
Go
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
var users = []User{
{ID: 1, Name: "张三", Age: 25},
{ID: 2, Name: "李四", Age: 30},
}
func main() {
r := gin.Default()
// 获取用户列表
r.GET("/users", func(c *gin.Context) {
c.JSON(200, gin.H{
"code": 0,
"data": users,
})
})
// 获取单个用户
r.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id")
for _, u := range users {
if fmt.Sprintf("%d", u.ID) == id {
c.JSON(200, gin.H{"data": u})
return
}
}
c.JSON(404, gin.H{"error": "用户不存在"})
})
// 创建用户
r.POST("/users", func(c *gin.Context) {
var user User
c.ShouldBindJSON(&user)
user.ID = len(users) + 1
users = append(users, user)
c.JSON(201, gin.H{"data": user})
})
// 更新用户
r.PUT("/users/:id", func(c *gin.Context) {
id := c.Param("id")
var updateUser User
c.ShouldBindJSON(&updateUser)
for i, u := range users {
if fmt.Sprintf("%d", u.ID) == id {
users[i] = updateUser
users[i].ID = u.ID
c.JSON(200, gin.H{"data": users[i]})
return
}
}
c.JSON(404, gin.H{"error": "用户不存在"})
})
// 删除用户
r.DELETE("/users/:id", func(c *gin.Context) {
id := c.Param("id")
for i, u := range users {
if fmt.Sprintf("%d", u.ID) == id {
users = append(users[:i], users[i+1:]...)
c.JSON(204, nil)
return
}
}
c.JSON(404, gin.H{"error": "用户不存在"})
})
r.Run(":8080")
}
状态码规范
| 操作 | 状态码 | 说明 |
|---|---|---|
| GET 成功 | 200 | 返回资源 |
| POST 成功 | 201 | 创建成功 |
| PUT/PATCH 成功 | 200 | 更新成功 |
| DELETE 成功 | 204 | 无内容返回 |
| 资源不存在 | 404 | Not Found |
| 参数错误 | 400 | Bad Request |
| 无权限 | 403 | Forbidden |
子资源设计
Go
// 用户文章子资源
r.GET("/users/:id/articles", listUserArticles)
r.GET("/users/:id/articles/:aid", getUserArticle)
r.POST("/users/:id/articles", createUserArticle)
// 简短别名(可选)
r.GET("/articles", listAllArticles)
URL 设计保持简洁一致,避免嵌套层级过多(建议不超过 3 层)。
要点总结
- URL 使用名词表示资源,HTTP 方法表示操作
- GET 获取、POST 创建、PUT/PATCH 更新、DELETE 删除
- 状态码语义明确,200/201/204/404 各有用途
- 子资源通过 URL 层级表示关系
- 响应格式统一,便于前端处理
📝 发现内容有误?点击此处直接编辑