Gin从入门到出门

Go Version: 1.22.3 last updated: 2024-10-27

net/http

Golang 原生的 net 库功能是非常丰富的。使用原生的 net/http 库也能编写出一个高效的 http Server。

  • http.Server: http 服务结构体,用来定义服务器相关的配置参数,比如:地址、超时时间等。
  • http.ServeMux: HTTP 服务的路由器,用于将不同的 URL 路径映射到对应的处理函数。ServeMux 实现了 http.Handler 接口,所以可以直接作为 http.ServerHandler

声明一个没有处理器的 http 服务器

func Run() {
httpServer := &http.Server{
Addr: ":8080",
Handler: nil,
}
if err := httpServer.ListenAndServe(); err != nil {
panic(err)
}
}

Handler 是一个接口,其中只需要实现一个 ServeHTTP 方法

type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}

编写一个 HttpHandler 并将它作为 HttpServer 的处理器

type MyHttpHandler struct {}

func (handler *MyHttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, world!"))
}

func Run() {
httpServer := &http.Server{
Addr: ":8080",
Handler: &MyHttpHandler{},
}
if err := httpServer.ListenAndServe(); err != nil {
panic(err)
}
}

在 Handler 里可以处理更加复杂的逻辑,比如判断请求方法,写入 JSON 数据

type User struct {
Name string `json:"name"`
Age int `json:"age"`
}

func (handler *MyHttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 拒绝处理 GET 请求
if r.Method == "GET" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
user := User{
Name: "John Doe",
Age: 30,
}
data, err := json.Marshal(user)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Write(data)
}

更加复杂的输入输出

func (handler *MyHttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 拒绝处理 GET 请求
if r.Method == "GET" {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
requestData, err := io.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
user := &User{}
err = json.Unmarshal(requestData, user)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}

user.Age++
data, err := json.Marshal(user)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Write(data)
}

ServeMux

Handle 接受一个 Handle 对象,HandleFunc 只需要传递一个函数。

func RunWithMux() {

mux := http.NewServeMux()

mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello world!"))
})

mux.HandleFunc("/index", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("index"))
})

server := &http.Server{
Addr: ":8080",
Handler: mux,
}

if err := server.ListenAndServe(); err != nil {
panic(err)
}
}

Gin

Gin 是用 Golang 编写的网络框架,高达 40 倍的性能。

特点:

  • 零分配路由
  • 快速
  • 中间件支持
  • 容错
  • JSON 校验
  • 路由分组
  • 错误管理

go get:

go get github.com/gin-gonic/gin