用 net/http 快速启动 Todo API 需1. 路由与业务分离用 ServeMux 注册后转交独立 handler2. 每次读取 req.Body 后必须 Close3. 统一 JSON 错误响应并设 Content-Type4. 结构体字段首字母大写json 标签5. ID 用 uuid.NewString() 生成并校验存在6. 手动处理 CORS显式响应 OPTIONS 并设置允许方法与来源。怎么用 net/http 快速启动一个 Todo API 服务Go 原生 net/http 完全够用不需要一开始就上 gin 或 echo。关键在于别把路由和业务逻辑混写否则加个字段就要改三处。用 http.ServeMux 注册路径但立刻转给独立 handler 函数比如 handleCreateTodo别在 http.HandleFunc 里写业务逻辑所有请求体必须显式调用 req.Body.Close()漏掉会导致连接不释放、后续请求卡住http.Error 默认返回 text/plain前端解析 JSON 失败时容易懵——统一用 json.NewEncoder(w).Encode(map[string]string{error: xxx}) 手动设 w.Header().Set(Content-Type, application/json; charsetutf-8)为什么 encoding/json 解析 POST 数据总出空结构体90% 是因为没读取或没关闭 req.Body或者 struct 字段没加导出标签。Go 的 JSON 解析器只认首字母大写的导出字段。必须先调用 io.ReadAll(req.Body) 或 json.NewDecoder(req.Body).Decode(todo)不能跳过读取直接解码struct 字段要加 json:title 标签且首字母必须大写Title string json:title写成 title string 就永远是零值如果前端发的是 application/x-www-form-urlencoded得用 req.ParseForm() req.FormValue(title)不是 json.Decode如何安全地给 Todo ID 生成和校验逻辑别用 math/rand 加时间戳拼接也别暴露自增数据库 ID。简单项目用 uuid.NewString()需 github.com/google/uuid最省心。生成 ID 后立刻存入 map 或 slice不要等收到请求才查——否则并发写 map 会 panicURL 路径里的 ID如 /todos/{id}必须在 handler 开头校验是否存在不存在就返回 404别让后续逻辑空跑如果用内存存储注意 map 不是并发安全的读多写少可用 sync.RWMutex 包一层写频繁就换 sync.Map但记住它不支持遍历为什么本地测试能过部署后 CORS 报错Go 默认不处理跨域浏览器拦的是 OPTIONS 预检请求不是你的 GET/POST。光加 Access-Control-Allow-Origin: * 不够。 Mokker AI AI产品图添加背景