#HTTP 服务端
Go 标准库 net/http 可以直接写 Web 服务。
Go 1.22 以后,标准库 ServeMux 支持更方便的路由写法:
mux.HandleFunc("GET /users/{id}", handler)#一、最小 HTTP 服务
package main
import (
"fmt"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /health", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "ok")
})
http.ListenAndServe(":8080", mux)
}运行:
go run .访问:
http://127.0.0.1:8080/health#二、返回 JSON
func writeJSON(w http.ResponseWriter, status int, data any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
json.NewEncoder(w).Encode(data)
}使用:
mux.HandleFunc("GET /users/{id}", func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
writeJSON(w, http.StatusOK, map[string]any{
"id": id,
"name": "张三",
})
})r.PathValue("id") 用来读取路径参数。
#三、解析 JSON 请求体
type CreateUserRequest struct {
Name string `json:"name"`
}
func createUser(w http.ResponseWriter, r *http.Request) {
var req CreateUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid json", http.StatusBadRequest)
return
}
writeJSON(w, http.StatusCreated, map[string]any{
"id": 1,
"name": req.Name,
})
}注册路由:
mux.HandleFunc("POST /users", createUser)#四、完整示例
package main
import (
"encoding/json"
"log"
"net/http"
)
type CreateUserRequest struct {
Name string `json:"name"`
}
type UserResponse struct {
ID string `json:"id"`
Name string `json:"name"`
}
func writeJSON(w http.ResponseWriter, status int, data any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
json.NewEncoder(w).Encode(data)
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /health", func(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, map[string]string{"status": "ok"})
})
mux.HandleFunc("GET /users/{id}", func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
writeJSON(w, http.StatusOK, UserResponse{ID: id, Name: "张三"})
})
mux.HandleFunc("POST /users", func(w http.ResponseWriter, r *http.Request) {
var req CreateUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid json", http.StatusBadRequest)
return
}
writeJSON(w, http.StatusCreated, UserResponse{ID: "1", Name: req.Name})
})
log.Println("server started at :8080")
log.Fatal(http.ListenAndServe(":8080", mux))
}#五、中间件
中间件本质上是包装 http.Handler。
func logMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println(r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}使用:
handler := logMiddleware(mux)
http.ListenAndServe(":8080", handler)#六、什么时候用框架
标准库已经能写 HTTP 服务。
框架如 Gin、Echo、Fiber 可以提供:
- 更方便的路由分组
- 参数绑定
- 中间件生态
- 统一响应封装
入门阶段先学标准库,有助于理解框架底层在做什么。

