fiber必须用app.listen()启动,不可复用net/http.server;c.params()取路由参数、c.queryparam()取查询参数,二者互不兼容;bodyparser必须传结构体指针且字段需导出并带json tag。

直接用 fiber.New() 启动,别套标准库 http.Server
Fiber 不是 net/http 的封装,它基于 fasthttp,所以不能也不该复用 http.Handler 或手动调用 http.ListenAndServe。常见错误是写成:http.ListenAndServe(":3000", app) —— 这会 panic,因为 app 不实现 http.Handler 接口。
正确做法只有一行:app.Listen(":3000")。它内部已封装监听、连接复用、goroutine 池等优化。如果你需要 HTTPS,直接传 ":443" 并配合 app.ListenTLS,不要自己套 http.Server 加 TLS 配置。
-
app.Listen()默认启用 keep-alive 和 connection reuse,无需额外配置 - 若需修改超时,用
fiber.Config{ReadTimeout: 10 * time.Second},而非改底层http.Server字段 - 禁用日志?直接跳过
middleware/logger,别试图 patchhttp.Server.ErrorLog
c.Params() 和 c.QueryParam() 别混用
路由参数(如 /user/:id)必须用 c.Params("id");查询参数(如 ?page=2)必须用 c.QueryParam("page")。两者底层存储不同,互不兼容。常见错误是把 /post?id=123 当成路由参数去取 c.Params("id"),结果返回空字符串。
更隐蔽的坑:当路由定义为 /api/v1/:version/posts,而请求是 /api/v1/2.1/posts?format=json,c.Params("version") 拿到的是 "2.1"(含点),但 c.QueryParam("format") 才是 "json" —— 它们从不交叉。
- 路径中带点、斜杠、% 编码字符?
c.Params()已自动解码,不用再url.PathUnescape - 多个同名 query 参数?
c.QueryParam("tag")只返回第一个,要用c.AllParams()["tag"]或c.Queries() - 没传参数时,
c.Params("x")返回空字符串,不是nil,别用== nil判断
JSON 解析别漏掉 &,c.BodyParser() 要传指针
c.BodyParser(user) 是错的,必须写成 c.BodyParser(&user)。因为 BodyParser 内部用 reflect 写入字段,非指针会导致 panic 或静默失败(值拷贝后修改无效)。这是新手最高频的 500 错误来源。
另外,结构体字段必须导出(首字母大写)且带 json tag,否则解析永远为空。例如:type User { name string `json:"name"` } 中 name 小写 → 解析失败;Name string 但没 tag → 字段被忽略。
- 解析失败时,
err不为nil,应显式检查并返回c.Status(400).SendString(err.Error()) - 想允许部分字段缺失?结构体字段加
omitemptytag,但注意这影响序列化,不影响解析 - 解析嵌套 JSON?确保嵌套字段也是导出 + 正确 tag,
BodyParser递归处理没问题
app.Use() 的顺序决定中间件生效范围
app.Use(mw1, mw2) 和 app.Get("/", handler) 的执行顺序严格依赖注册顺序。所有 app.Use() 注册的中间件,都会在匹配到任何路由前执行;而 app.Get("/api", mw3, handler) 中的 mw3 只对 /api 生效。
典型错误是把 logger 放在 recover 后面 —— 一旦 handler panic,logger 就收不到结束日志;或者把 cors 放在 bodyparser 后面,导致预检请求(OPTIONS)没被 cors 拦截,直接 404。
- 全局中间件(如日志、CORS)必须用
app.Use(),且放在路由注册之前 - 路由级中间件(如权限校验)应直接挂在
app.Post("/admin", auth, handler)上 -
app.Use("/", mw)中的"/"是前缀,不是精确路径,/user/123也会触发
最易被忽略的点:Fiber 的上下文 *fiber.Ctx 不是线程安全的,不能跨 goroutine 传递或保存引用。比如在 go func() { c.SendString(...) }() 里调用会 panic —— 因为 c 生命周期只到 handler 返回为止。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











