无法访问 /api/contacts 是因为 gin.Default() 仅初始化引擎并挂载日志与恢复中间件,未注册任何业务路由;必须显式调用 r.Group("/api") 创建路由组,并在其中注册 api.GET("/contacts", handler) 等具体路由。

为什么用 gin.Default() 启动服务后无法访问 /api/contacts
默认路由组没注册,gin.Default() 只挂载了基础中间件,所有业务路由必须显式添加。常见错误是写了 r := gin.Default() 就直接写 handler,但没调用 r.GET() 或 r.Group()。
正确做法是先定义路由组,再注册接口:
r := gin.Default()
api := r.Group("/api")
{
api.GET("/contacts", getContactsHandler)
api.POST("/contacts", createContactHandler)
}
r.Run(":8080")
- 别把 handler 函数体直接塞进
r.GET(),先写函数再传名,方便测试和复用 - 如果用了
gin.New()而非gin.Default(),记得手动加gin.Logger()和gin.Recovery(),否则 500 错误不打日志 - 开发时建议在
r.Use(gin.Logger())后加一行r.Use(gin.CustomRecovery(func(c *gin.Context, err interface{}) { ... })),避免 panic 后整个服务挂掉
如何让 Contact 结构体支持 JSON 输入且兼容空字段
Go 的 struct 字段默认首字母大写才导出,JSON 解析失败常因字段未导出或 tag 写错。比如 name string 不会参与 JSON 编解码,必须写成 Name string 并配 json tag。
另外,前端可能传空字符串或缺失字段,需用指针或 omitempty 控制行为:
立即学习“go语言免费学习笔记(深入)”;
type Contact struct {
ID uint `json:"id"`
Name string `json:"name"`
Phone string `json:"phone,omitempty"`
Email string `json:"email,omitempty"`
Dept *string `json:"dept,omitempty"` // 允许 null
}
-
omitempty对空字符串、零值 slice/map、nil 指针都生效,但对非 nil 空指针(如 new(string))无效 - 若数据库字段允许 NULL,对应 Go 字段建议用指针类型(
*string,*int64),避免零值误写入 - 接收 POST 数据时,务必用
c.ShouldBindJSON(&contact)而非c.BindJSON(),前者出错不终止请求,可自定义返回 400
用 gorilla/mux 还是坚持 Gin 原生路由?
Gin 自带的 RouterGroup 已足够处理通讯录这类 CRUD 场景,没必要引入 gorilla/mux。它的正则路由和子路由嵌套在 Gin 里都能用更轻量方式实现。
例如需要按 ID 获取单个联系人,Gin 写法简洁清晰:
api.GET("/contacts/:id", getContactByIDHandler)
// handler 中用 c.Param("id") 取值,自动做类型转换(需自行转 int)
- 别为了“看起来更专业”而加多余依赖,Gin 的
:id和*path已覆盖 95% 路由需求 - 如果真要校验 ID 格式(比如只接受数字),用
c.Param("id")取出后手动strconv.Atoi(),别指望框架自动做 - 路径参数和查询参数(
c.Query("q"))不要混用:搜索用 query,资源定位用 path
为什么本地测试能跑,部署到 Linux 服务器就报 bind: permission denied
因为普通用户不能监听 1024 以下端口,而 r.Run(":80") 试图绑定 80 端口。这不是 Gin 的问题,是操作系统限制。
- 开发用
:8080或:3000,上线改用反向代理(Nginx)转发 80 → 8080,别硬扛权限问题 - 如果非要用低权端口,可用
setcap 'cap_net_bind_service=+ep' ./your-binary,但运维风险高,不推荐 - 检查
netstat -tuln | grep :8080确认端口是否被占用,Docker 容器内还要确认EXPOSE和-p参数一致
通讯录 API 的核心其实是数据一致性与边界控制——比如手机号重复校验、部门字段长度截断、ID 查询时的 404 处理,这些比框架选型更值得花时间抠细节。


















