推荐用 chi 路由器:路径参数用 {id} 并通过 chi.URLParam(r, "id") 获取,查询参数需手动解析并封装为结构体;JSON 解析须用指针接收、导出字段加 json tag、补充业务校验;错误响应统一用 map[string]string 返回并设 http.StatusBadRequest;日志须用 zerolog/zap 等结构化库,注入 trace ID 到 context。

Go 语言写 RESTful API 不需要框架也能做,但用 net/http 手动处理路由、解析 JSON、错误响应容易漏掉边界情况;实际项目中推荐用轻量级路由器(如 gorilla/mux 或 chi),它们不侵入业务逻辑,又解决路径参数、中间件、预处理等刚需。
如何用 chi 定义带路径参数和查询参数的路由
chi 的路由语法简洁,支持嵌套和中间件,比原生 net/http 更易维护。路径参数用 {id} 表示,查询参数需手动从 r.URL.Query() 提取。
- 路径参数在 handler 中用
chi.URLParam(r, "id")获取,注意返回空字符串时需校验 - 查询参数如
?page=1&limit=20,建议封装一个parseQueryParams(r *http.Request)函数统一转成 struct,避免每个 handler 重复写strconv.Atoi - 不要把路径参数当可选字段用——
/users/{id}和/users必须分开注册,chi不会自动 fallback
示例:
router.Get("/users/{id}", getUserHandler)
router.Get("/users", listUsersHandler)
JSON 请求体解析失败时如何返回清晰错误
直接用 json.Unmarshal 解析 r.Body,出错时默认只返回 400 Bad Request,前端很难定位是字段名错了、类型不对,还是少了必填字段。
- 始终用指针接收结构体(
json.Unmarshal(r.Body, &req)),否则解析后字段值不会写入 - 结构体字段必须导出(首字母大写),且加
json:"field_name"tag,否则反序列化为零值 - 对关键字段加自定义校验(如
if req.Email == ""),别依赖json包的 “omitempty” 做业务判断 - 错误响应统一用
map[string]string{"error": "xxx"}格式,HTTP 状态码设为http.StatusBadRequest
为什么不要在 handler 里直接调用 log.Printf
看似方便,但会导致日志缺乏上下文(比如无法关联请求 ID、无法区分 debug/info/warn)、难以接入集中式日志系统,且并发写文件可能成为瓶颈。
该系统由帝国开发工作组独立开发,是一个经过完善设计的适用于Linux/windows/Unix等环境下高效的网站解决方案。从帝国新闻系统1.0版至今天的帝国网站管理系统,它的功能进行了数次飞跃性的革新,使得网站的架设与管理变得极其轻松。 它采用了系统模型功能:用户通过此功能可直接在后台扩展与实现各种系统,如产品、房产、供求、等等系统,因此特性,[1] 帝国CMS又被誉为“万能建站工具”;采用了
立即学习“go语言免费学习笔记(深入)”;
- 用结构化日志库(如
zerolog或zap),初始化一次全局 logger,handler 中通过logger.With().Str("user_id", userID).Info()追加字段 - 为每个请求生成唯一 trace ID(如用
uuid.NewString()),通过中间件注入到context.Context,后续所有日志、DB 查询、HTTP 调用都带上它 - 避免在 handler 里写
fmt.Println或裸log.Fatal—— 这会让服务 panic 退出,而不是返回500并继续运行
真正难的不是写出能跑的接口,而是让每个错误都有可追溯的上下文、每个参数都有明确的校验边界、每次部署都不用改日志采集配置。这些细节在第一个 PR 里常被跳过,到线上查问题时才暴露出来。









