引入
Web 服务是当今应用的核心,Go 标准库自带的 net/http 包就能搭建 HTTP 服务器和客户端,不需要第三方框架。理解 net/http 包,就能用 Go 快速写出 REST API、爬虫、反向代理等网络应用。
正文
定义
定义
net/http包提供 HTTP 服务器和客户端 功能。服务器端负责监听端口、接收请求、返回响应;客户端负责发起 HTTP 请求。内置路由匹配和中间件支持,是 Go Web 开发的基础。
语法
import "net/http"
// 启动服务器
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello"))
})
http.ListenAndServe(":8080", nil)
// 发起客户端请求
resp, err := http.Get("http://localhost:8080/hello")例子
最简单的 HTTP 服务器
package main
import (
"fmt"
"net/http"
)
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello world")
}
func main() {
http.HandleFunc("/hello", hello)
http.ListenAndServe(":8080", nil)
}HandleFunc 注册路由,ListenAndServe 启动服务器。访问 http://localhost:8080/hello 就能看到 hello world。
处理请求参数
func handler(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
method := r.Method
body, _ := io.ReadAll(r.Body)
defer r.Body.Close()
fmt.Fprintf(w, "method=%s, name=%s, body=%s", method, name, string(body))
}r.Method 获取请求方法,r.URL.Query() 解析 URL 参数,r.Body 读取请求体。
返回 JSON 响应
func apiHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"code": 0, "msg": "ok"}`))
}w.Header().Set() 设置响应头,w.WriteHeader() 设置状态码,w.Write() 写入响应体。
HTTP 客户端
// GET 请求
resp, err := http.Get("https://example.com")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
// POST 请求
resp, err := http.Post("https://example.com/api", "application/json",
strings.NewReader(`{"key":"value"}`))
defer resp.Body.Close()http.Get 和 http.Post 是最简写法。resp.Body 是 io.Reader,用完要 Close()。
自定义客户端
client := &http.Client{
Timeout: 10 * time.Second,
}
req, _ := http.NewRequest("PUT", "https://example.com/api/1",
strings.NewReader(`{"name":"tom"}`))
req.Header.Set("Authorization", "Bearer token123")
resp, err := client.Do(req)
defer resp.Body.Close()http.NewRequest 可以设置任意方法和请求头,client.Do 发送请求。需要设超时就用自定义客户端,默认客户端没有超时。
中间件
func logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
fmt.Printf("%s %s %v\n", r.Method, r.URL.Path, time.Since(start))
})
}
mux := http.NewServeMux()
mux.HandleFunc("/api", apiHandler)
http.ListenAndServe(":8080", logging(mux))中间件就是一个函数,包装原始 Handler 添加额外逻辑。Go 1.22+ 的 ServeMux 支持方法路由如 GET /api/users/{id}。
常见写法
| 写法 | 说明 |
|---|---|
http.ListenAndServe(addr, handler) | 启动 HTTP 服务器 |
http.HandleFunc(pattern, handler) | 注册路由处理函数 |
http.NewServeMux() | 创建自定义路由多路复用器 |
http.Get(url) | 发起 GET 请求 |
http.Post(url, contentType, body) | 发起 POST 请求 |
http.NewRequest(method, url, body) | 创建自定义请求 |
client.Do(req) | 用自定义客户端发送请求 |
r.URL.Query().Get(key) | 获取 URL 查询参数 |
r.Method | 获取请求方法 |
w.Header().Set(k, v) | 设置响应头 |
w.WriteHeader(code) | 设置响应状态码 |
http.FileServer(http.Dir("./static")) | 静态文件服务器 |
特点
net/http内置 HTTP 服务器,不需要 Apache 或 Nginx 就能独立运行HandlerFunc让普通函数满足Handler接口,注册路由很方便- 客户端的
resp.Body必须Close(),否则连接泄漏 - 默认客户端没有超时设置,生产环境务必自定义
Client - Go 1.22+ 的
ServeMux支持方法和路径参数,不再需要第三方路由库 - 中间件通过函数嵌套实现,简洁且灵活
理解
net/http 的设计很 Go 风格——接口驱动,组合优先。服务器端核心就是 Handler 接口,任何实现了 ServeHTTP 方法的类型都能处理请求。客户端用起来也简单,Get / Post 一行搞定,复杂场景用 NewRequest + client.Do。中间件就是套娃式的函数包装,理解了这个模式,整个 Go Web 生态(gin、echo)都是这套路。
引出
HTTP 请求和响应经常要传 JSON 数据,手动拼字符串太麻烦。接下来看 json 包,学习怎么在 Go 结构体和 JSON 之间自动转换。