删除操作必须显式注册 DELETE 路由,校验 ID 合法性与权限,查-验-删三步执行,区分状态码返回,批量删除需限流、事务与异步处理。

删除操作必须显式处理 DELETE 路由
Fiber 默认不自动绑定任何 HTTP 方法,DELETE 请求不会被 GET 或 POST 路由捕获。你得手动注册对应路由,否则前端发了 DELETE 请求,后端直接 404。
常见错误是误用 app.Post("/api/user/:id", ...) 处理删除逻辑,这会让接口语义混乱,也容易和真正提交表单的 POST 冲突。
正确做法:
app.Delete("/api/users/:id", func(c *fiber.Ctx) error {
id := c.Params("id")
// 实际删除逻辑
return c.Status(fiber.StatusOK).JSON(fiber.Map{"success": true})
})
- 路径参数名(如
:id)需与c.Params("id")中字符串一致,大小写敏感 - 别忘了校验
id是否为空或非法格式,否则可能触发数据库空值错误 - 如果使用 UUID,建议在路由中加正则约束:
/api/users/:id([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})
数据库删除前务必做存在性检查和权限验证
直接执行 DELETE FROM users WHERE id = ? 并返回成功,是典型的安全隐患。用户可能篡改 URL 删除他人数据,或对不存在的 ID 发起请求导致误判。
真实场景中应分三步:查、验、删。
示例(以 GORM 为例):
var user User
if err := db.Where("id = ? AND status != ?", id, "deleted").First(&user).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "user not found"})
}
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "db error"})
}
// 检查当前登录用户是否有权删除该 user(比如 owner_id == c.Locals("user_id"))
if user.OwnerID != c.Locals("user_id").(uint) {
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "no permission"})
}
// 执行软删或硬删
db.Delete(&user)
- 硬删(
DELETE)不可逆,生产环境更推荐软删(更新deleted_at字段) - 不要依赖前端传来的
user_id做权限判断,必须从中间件已解析并存入c.Locals的可信上下文中取 - GORM 的
First()查不到会返回gorm.ErrRecordNotFound,不是nil,这点容易写错
返回值要区分删除成功、未找到、无权限等状态码
很多实现直接统一返回 200 OK,掩盖了业务逻辑差异。前端无法据此决定跳转、刷新或提示用户“目标已不存在”。
标准做法是按结果返回不同状态码:
- 成功删除 →
200 OK或204 No Content(推荐后者,无响应体时更语义准确) - 记录不存在 →
404 Not Found - 认证失败 →
401 Unauthorized - 权限不足 →
403 Forbidden - 数据库错误 →
500 Internal Server Error
注意:c.Status(204).Send(nil) 是最轻量的删除成功响应;若返回 JSON,200 更合适,但别混用。
批量删除需额外控制并发与事务边界
当接口支持 DELETE /api/users?ids=1,2,3 这类批量操作时,风险陡增:一次删太多行可能锁表、超时、OOM。不能简单把查询参数拼进 SQL。
实操要点:
- 限制最大数量,例如
ids参数最多允许 100 个 ID,超出直接400 Bad Request - 用
IN查询前先做类型校验和去重,防止注入或重复执行 - 涉及多行更新/删除,必须包裹在事务中:
tx := db.Begin(); defer tx.Rollback(),成功才Commit - 考虑异步化:对超大批量(如 > 1000),返回
202 Accepted+ 任务 ID,后台队列处理
最容易被忽略的是事务回滚时机——别只在 err != nil 时回滚,也要在中间件提前中断(如权限校验失败)时确保事务不残留。

















