用 net/http 启原型服务最轻最快,应避免 Gin/Echo 的路由冲突与中间件干扰;正确做法是直接使用 http.HandlerFunc 配合 httptest.NewServer,显式注册路由、手动处理 JSON、封装带锁内存存储、用 httptest.Server 做可控 Mock,并严格匹配 JSON 字段名与结构体 tag。

用 net/http 而不是 Gin/Echo 启原型服务
真要跑通第一个 HTTP 接口,net/http 是最轻、最快、零依赖的选择。Gin 或 Echo 在原型阶段反而引入路由冲突、中间件干扰、测试端口占用等副作用。
常见错误是直接在测试里调 gin.Default(),结果 http.DefaultServeMux 被覆盖,后续 httptest.NewServer 失效;或者多个测试并发时因复用全局 mux 导致 panic。
- 正确姿势:写一个
http.HandlerFunc,传给httptest.NewServer,拿到 URL 就能发请求 - 需要多路径?用
http.ServeMux显式注册,不碰默认 mux - 返回 JSON?手动设
Content-Type,用json.NewEncoder(w).Encode(),别依赖框架的c.JSON() - 想加日志或简单鉴权?在 handler 里写几行 if/else,别急着引入中间件链
用内存 map + sync.RWMutex 模拟数据库
原型阶段数据库连接、迁移、ORM 初始化全是拖慢节奏的负担。用 map[string]interface{} 或结构体切片配合 sync.RWMutex,5 行代码就能支撑 CRUD。
容易踩的坑是直接用全局变量存数据,导致并发写 panic;或忘了加锁,GET 和 POST 同时操作 map 触发 fatal error: concurrent map writes。
立即学习“go语言免费学习笔记(深入)”;
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 定义一个带锁的容器类型,比如
type Store struct { mu sync.RWMutex data map[string]*Post } - 所有读操作用
mu.RLock(),写操作用mu.Lock() - 避免在 handler 里直接操作裸 map,封装成
store.Get(id)、store.Create(p) - 如果原型要演示“分页”或“搜索”,用
for range过滤切片,别提前引入 SQL 或全文索引
用 httptest.Server 做可控 API Mock
验证客户端逻辑时,别让真实后端拖住进度。httptest.Server 启一个临时服务,返回固定 JSON 或动态状态码,比配 nginx 或起 mock server 快 10 倍。
典型问题是 Mock 返回字段名和实际结构体不一致,json.Unmarshal 静默失败——字段保持零值,你却以为是网络没通。
- 从真实响应里拷贝 JSON 字符串,粘贴进 handler 的
json.NewEncoder(w).Encode() - 需要模拟错误?
w.WriteHeader(http.StatusServiceUnavailable)后再写 body - 模拟延迟?
time.Sleep(100 * time.Millisecond)比改 client timeout 更直观 - 每次测试都调
srv := httptest.NewServer(handler),测完defer srv.Close(),绝不复用
结构体字段命名必须和 JSON key 严格对应
Go 的 encoding/json 包对字段名大小写、tag、嵌套层级极其敏感。原型里手写结构体,最容易漏掉 json: tag 或写错大小写,导致反序列化后字段为空。
比如后端返回 {"user_id": 123},你定义 UserID int `json:"userId"`,字段就永远是 0——包不会报错,只会跳过赋值。
- 先用
map[string]interface{}解一次响应,fmt.Printf("%+v", m)确认 key 名和类型 - 结构体字段名首字母大写(导出),tag 里的 key 小写且完全匹配返回值,如
ID int `json:"user_id"` - 含 slice 或 map 字段?确保初始化,比如
Tags []string `json:"tags"`,别留 nil - 不想手写?从 OpenAPI spec 用
oapi-codegen生成 struct,比人工靠谱
原型开发真正卡点不在语法,而在“复制行为是否真正独立”和“字段映射是否精确”。Clone() 方法写得再漂亮,JSON tag 错一个字符,前端就收不到数据;sync.RWMutex 加得再严谨,字段名拼错,业务逻辑照样空转。动手前花 30 秒确认这两件事,比查文档快得多。

















