http.HandleFunc 不够用因仅支持静态路径匹配,无法解析动态段如 /users/123;应选 chi 等路由库,用 chi.URLParam 安全取值,并将解析、校验、查询拆分为可测函数。
用
搭建最简 RESTful 路由时,为什么
不够用?
因为
只支持固定路径字符串匹配,无法解析
中的
这类动态段。你得自己写字符串切分和类型转换,容易出错且不可维护。
实操建议:
立即学习
“
go语言免费学习笔记(深入)
”;
优先使用轻量路由库,如
或
(推荐
,API 设计更清晰、中间件链更自然)
避免手写正则匹配路径——
的
直接取值,类型安全
别在 handler 里做太多逻辑,把解析、校验、DB 查询拆成独立函数,方便单元测试
中如何正确处理 JSON 请求体并捕获常见解码错误?
直接
读
容易忽略
、
等错误,导致 500 泄露内部信息或静默失败。
实操建议:
立即学习
“
go语言免费学习笔记(深入)
”;
统一用封装函数解析 JSON,例如:
在中间件中检查
,不匹配直接返回 415
结构体字段必须加
tag,且注意导出(首字母大写),否则解码始终为零值
RESTful 接口返回错误时,
和自定义 JSON 错误响应哪个更合适?
返回纯文本,前端难解析;但直接写 JSON 又容易漏设
或状态码,导致前端收到 200 却含错误内容。
实操建议:
立即学习
“
go语言免费学习笔记(深入)
”;
所有错误响应走统一函数,例如:
区分错误类型:参数校验失败用 400,资源不存在用 404,权限问题用 403,服务异常用 500
不要在错误响应里暴露数据库字段名、堆栈或内部路径(如
)
用
查询时,为什么
报
但接口没返回 404?
这是最常被忽略的点:
本身不报这个错,真正触发它的是
或
返回
后未检查
。很多开发者只判断
就返回空结构体,结果 200 响应了 null。
实操建议:
立即学习
“
go语言免费学习笔记(深入)
”;
查单条记录用
,它会自动返回
;捕获后显式返回 404
查列表用
循环,循环结束后务必调
判断是否有底层错误
别用
忽略错误——Go 的错误必须显式处理
Gin 或 Echo 这类框架能省掉部分样板代码,但底层逻辑一致。真正容易翻车的,往往不是选什么框架,而是忘了
、漏了
、或者把
当普通错误透传给前端。
net/httphttp.HandleFunchttp.HandleFunc/users/123123gorilla/muxchichichichi.URLParam(r, "id")chijson.Decoder.Bodyio.EOFjson.SyntaxErrorfunc parseJSON(r *http.Request, v interface{}) error {
defer r.Body.Close()
if r.ContentLength == 0 {
return errors.New("empty request body")
}
if err := json.NewDecoder(r.Body).Decode(v); err != nil {
var syntaxErr *json.SyntaxError
if errors.As(err, &syntaxErr) {
return fmt.Errorf("invalid JSON at position %d", syntaxErr.Offset)
}
return fmt.Errorf("invalid request payload: %w", err)
}
return nil
}Content-Type: application/jsonjson:http.Errorhttp.ErrorContent-Typefunc writeError(w http.ResponseWriter, status int, msg string) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(status)
json.NewEncoder(w).Encode(map[string]string{"error": msg})
}"failed to query users table"database/sqlScansql: no rows in result setrows.Scan()rows.Err()rows.Next()falserows.Err()rows.Next()db.QueryRow().Scan()sql.ErrNoRowsfor rows.Next()rows.Err()_ = db.QueryRow(...).Scan(...)rows.Err()Content-Typejson.SyntaxError