5行代码即可用net/http启动最简API服务:使用http.HandleFunc注册路由、w.Header().Set设JSON类型、json.NewEncoder返回响应、http.ListenAndServe监听":8080"。

用 net/http 启一个最简 API 服务,5 行代码够用
不需要框架,net/http 自带的 http.HandleFunc 和 http.ListenAndServe 就能跑通基础验证。重点不是“搭环境”,而是让接口立刻可调用、可观察响应体和状态码。
常见错误是直接写 handler 却忘了启动 server,或监听了 localhost:8080 却用 127.0.0.1:8080 测试——两者在 macOS 或某些容器网络下行为不一致。
- 监听地址推荐用
":8080"(即所有网卡),避免绑定localhost导致 curl 失败 - handler 中务必显式设置
w.Header().Set("Content-Type", "application/json"),否则前端或curl -H "Accept: application/json"可能解析异常 - 返回前加
return防止后续逻辑意外执行(尤其有多个 if 分支时)
package main
import (
"encoding/json"
"net/http"
)
func main() {
http.HandleFunc("/api/ping", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
})
http.ListenAndServe(":8080", nil)
}
用 httptest 做无端口依赖的单元级接口测试
本地验证不等于手动 curl。真正快的验证方式是写个 TestXxx 函数,用 httptest.NewServer 或 httptest.NewRecorder 拦截请求,不占端口、不启真实网络、秒级完成。
容易踩的坑:用 NewServer 时忘记调 server.Close(),导致测试进程残留;用 NewRecorder 时直接传 nil 给 handler 而没构造 *http.Request,结果 r.URL.Query() panic。
立即学习“go语言免费学习笔记(深入)”;
-
NewRecorder适合测单个 handler 函数,不走路由匹配,适合验证业务逻辑分支 -
NewServer适合集成测试,模拟真实 HTTP 客户端行为(比如验证重定向、Header 回传) - 测试 POST JSON 时,记得用
strings.NewReader(`{"id":1}`)构造Body,并设Content-Type: application/json
快速 mock 第三方 API:用 gock 拦截 outbound 请求
你的 API 依赖外部服务(比如调了 https://api.example.com/users),但不想每次测试都连线上环境?gock 可以在测试中拦截 HTTP client 发出的请求,并返回预设响应。
注意:必须在 http.DefaultClient 或自定义 client 上启用 gock,且需在测试末尾调 gock.Off() 清理,否则后续测试可能被污染。
- mock 前先
gock.DisableNetworking(),防止漏掉未 mock 的请求导致测试失败 - 路径匹配支持正则,比如
gock.New("https://api.example.com").Get("/users/\\d+") - 返回 JSON 时用
JSON(map[string]interface{}{"name": "test"}),比手拼字符串更安全
调试时加日志中间件,但别提交到主干
开发阶段需要看清进来的请求方法、路径、查询参数、响应状态码,临时加个中间件比反复改 fmt.Println 干净得多。但上线前必须删掉或用 build tag 控制。
典型陷阱:中间件里读了 r.Body 但没放回去,导致下游 handler 读不到 body;或者 log 打印了敏感字段(如 Authorization header)。
- 用
io.TeeReader把 body 流同时写入 buffer 和原 reader,避免 body 消失 - log 输出建议包含
r.RemoteAddr+r.Method+r.URL.Path+status,四要素足够定位问题 - 加
//go:build debug标签,编译时用go run -tags debug控制是否启用
net/http 边界条件的熟悉,以及知道什么时候该用 httptest、什么时候该用 gock——而不是堆工具。










