如何使用Golang构建基础的REST API_Golang REST API接口设计与实现方法

发布时间 - 2026-01-03 00:00:00    点击率:
net/http 可直接启动轻量 REST 服务:用 http.ListenAndServe 启动,http.HandleFunc 注册严格路径路由,handler 中需手动读取并校验 req.Body、设置 Content-Type 为 application/json;注意 req.Body 只能读一次、ServeMux 前缀匹配陷阱及显式处理 404。

net/http 启动最简 REST 服务,别急着上框架

Go 自带的 net/http 足够支撑大多数基础 API 场景,启动快、依赖少、逻辑透明。过度依赖 ginecho 容易掩盖路由分发、中间件执行顺序、错误传播路径等关键细节。

  • 直接调用 http.ListenAndServe(":8080", nil) 即可启动服务,nil 表示使用默认的 http.DefaultServeMux
  • http.HandleFunc("/users", handlerFunc) 注册路由,注意路径末尾不自动匹配子路径(/users/users/123
  • 所有 handler 函数签名必须是 func(http.ResponseWriter, *http.Request),返回值不能传 error,需手动写入响应
  • 别在 handler 里 panic——Go 的 HTTP server 不会 recover,一次 panic 就整条连接挂掉

解析 JSON 请求体时,json.Unmarshal 前必须先读取 req.Body

常见错误是直接对 req.Body 多次调用 json.Unmarshal,结果第二次开始全为零值。因为 req.Body 是单向流,读完即空。

  • 务必用 io.ReadAll(req.Body) 一次性读出全部字节,再传给 json.Unmarshal
  • 记得在读取前检查 req.Methodreq.Header.Get("Content-Type"),避免对 GET 请求尝试读 body
  • 若需复用 body(如日志或鉴权),应提前用 req.Body = io.NopCloser(bytes.NewBuffer(data)) 包装回 io.ReadCloser
data, err := io.ReadAll(req.Body)
if err != nil {
    http.Error(w, "bad request body", http.StatusBadRequest)
    return
}
var u User
if err := json.Unmarshal(data, &u); err != nil {
    http.Error(w, "invalid JSON", http.StatusBadRequest)
    return
}

返回 JSON 响应时,Content-Type 必须显式设置为 application/json; charset=utf-8

不设 header 导致前端 fetch().json() 报错 “Unexpected token”,浏览器可能按 text/html 解析,中文变乱码。

  • w.Header().Set("Content-Type", "application/json; charset=utf-8") 显式声明
  • 避免用 fmt.Fprintf 直接输出 JSON 字符串——它不处理转义、不控制精度、不兼容结构体字段 tag(如 json:"name,omitempty"
  • json.NewEncoder(w).Encode(v) 替代 json.Marshal + Write,前者支持流式编码,内存更友好
w.Header().Set("Content-Type", "application/json; charset=utf-8")
if err := json.NewEncoder(w).Encode(map[string]string{"status": "ok"}); err != nil {
    http.Error(w, "encode error", http.StatusInternalServerError)
}

路由设计要避开 http.ServeMux 的路径匹配陷阱

http.ServeMux 只做前缀匹配,且不区分 trailing slash,/api 会意外匹配到 /api/users 并交给同一 handler,但你没实现子路径逻辑。

立即学习“go语言免费学习笔记(深入)”;

  • 注册路由时严格写全路径:http.HandleFunc("/api/users", listUsers),不要只写 /api
  • 需要层级路由,自己做路径分割:strings.Split(strings.TrimPrefix(req.URL.Path, "/api"), "/")
  • 404 处理不能依赖框架自动 fallback——http.NotFound(w, req) 必须显式调用,否则返回空 200
  • 如果 URL 含查询参数(如 /users?limit=10),用 req.URL.Query().Get("limit") 获取,别手撕 req.URL.RawQuery
真正卡住人的从来不是语法,而是 req.Body 只能读一次、http.ServeMux 不校验路径结尾、JSON 编码器和字符串拼接混用这些细节。写完一个 handler,先 curl 测一遍 status code 和 Content-Type,比跑通单元测试还管用。


# html  # js  # 前端  # json  # go  # golang  # 编码  # 浏览器  # app  # 字节  # usb  # curl  # ai  # 路由  # 中间件  # gin  # echo 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 郑州企业网站制作公司,郑州招聘网站有哪些?  Laravel如何保护应用免受CSRF攻击?(原理和示例)  Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作  如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】  Laravel如何优化应用性能?(缓存和优化命令)  作用域操作符会触发自动加载吗_php类自动加载机制与::调用【教程】  如何选择可靠的免备案建站服务器?  百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧  JS碰撞运动实现方法详解  如何自定义建站之星网站的导航菜单样式?  微信小程序 require机制详解及实例代码  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法  如何生成腾讯云建站专用兑换码?  深圳网站制作培训,深圳哪些招聘网站比较好?  Android okhttputils现在进度显示实例代码  如何在景安云服务器上绑定域名并配置虚拟主机?  通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】  微信小程序制作网站有哪些,微信小程序需要做网站吗?  手机软键盘弹出时影响布局的解决方法  如何快速搭建FTP站点实现文件共享?  如何破解联通资金短缺导致的基站建设难题?  Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  Laravel中的Facade(门面)到底是什么原理  如何在IIS7中新建站点?详细步骤解析  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用  如何在万网主机上快速搭建网站?  node.js报错:Cannot find module 'ejs'的解决办法  Claude怎样写结构化提示词_Claude结构化提示词写法【教程】  如何在橙子建站上传落地页?操作指南详解  Chrome浏览器标签页分组怎么用_谷歌浏览器整理标签页技巧【效率】  南京网站制作费用,南京远驱官方网站?  网站图片在线制作软件,怎么在图片上做链接?  最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  三星、SK海力士获美批准:可向中国出口芯片制造设备  Python制作简易注册登录系统  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  php 三元运算符实例详细介绍  香港服务器如何优化才能显著提升网站加载速度?  JavaScript数据类型有哪些_如何准确判断一个变量的类型  iOS验证手机号的正则表达式  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  iOS正则表达式验证手机号、邮箱、身份证号等  魔毅自助建站系统:模板定制与SEO优化一键生成指南