博客 / 詳情

返回

Gin筆記二之gin.Engine和路由設置

本文首發於公眾號:Hunter後端

原文鏈接:Gin筆記二之gin.Engine和路由設置

這一篇筆記主要介紹 gin.Engine,設置路由等操作,以下是本篇筆記目錄:

  1. gin.Default() 和 gin.New()
  2. HTTP 方法
  3. 路由分組與中間件

1、gin.Default() 和 gin.New()

前面第一篇筆記介紹,創建一個 gin 的路由引擎使用的函數是 gin.Default(),返回的類型是 *gin.Engine,我們可以使用其創建路由和路由組。

除了這個函數外,還有一個 gin.New(),其返回的也是 *gin.Engine,但是不一樣的是 gin.Default() 會對 gin.Engine 添加默認的 Logger()Recovery() 中間件。

這兩個函數大致內容如下:

func New(opts ...OptionFunc) *Engine {
    ...
}

func Default(opts ...OptionFunc) *Engine {
    ...
    engine := New()
    engine.Use(Logger(), Recovery())
    ...
}

我們使用第一篇筆記中使用 debug 模式運行系統後輸出的信息可以再看一下:

[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /test                     --> main.main.func1 (3 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :9898

我們使用的是 gin.Default() 運行的系統,所以在第一行告訴我們創建了一個帶有 Logger and Recovery 中間件的 Engine

同時第三行輸出路由信息的地方,標明瞭這個路由指向的處理函數,後面的括號裏是 3 handlers,這個意思是除了我們處理路由的 handler,還有兩個默認的中間件 handler,也就是這裏的 Logger()Recovery() 中間件。

下面介紹一下 Logger()Recovery() 這兩個 handler 的作用。

1. Logger()

默認的 Logger() 會輸出接口調用的信息,比如第一篇中我們定義了一個 /test 接口,當我們調用這個接口的時候,控制枱會輸出下面這條信息:

[GIN] 2025/08/19 - 23:15:26 | 200 |      36.666µs |       127.0.0.1 | GET      "/test"

可以看到日誌中會包含請求時間、返回的 HTTP 狀態碼、請求耗時、調用方 ip、請求方式和接口名稱等。

這條日誌信息的輸出就是 Logger() 這個中間件起的作用。

在其內部,會調用一個 LoggerWithConfig() 函數,獲取到請求的 ip、記錄調用時間、調用方式等信息,然後進行輸出,下面是部分源碼信息:

param.TimeStamp = time.Now()
param.Latency = param.TimeStamp.Sub(start)

param.ClientIP = c.ClientIP()
param.Method = c.Request.Method
param.StatusCode = c.Writer.Status()
param.ErrorMessage = c.Errors.ByType(ErrorTypePrivate).String()

2. Recovery()

Recovery() 中間件則可以為我們捕獲程序中未處理的 panic,記錄錯誤信息並返回 500 狀態碼信息,比如我們在第一篇筆記中使用的 TestHandler 函數,我們在其中加一個除數為 0 的錯誤:

func TestHandler(c *gin.Context) {
    response := TestResponse{
        Code:    0,
        Message: "success",
    }
    a := 0
    fmt.Println(1 / a)
    c.JSON(http.StatusOK, response)
}

在接口調用的時候,如果我們使用的是 gin.Default(),那麼客户端不會報錯,而是會收到一個 HTTP 狀態碼為 500 的報錯信息,而如果使用的是 gin.New(),客户端則會直接發生錯誤。

總的來説,Logger()Recovery() 這兩個的中間件是 gin 框架為我們默認添加的對於開發者來説較為友好的兩個操作,在後面介紹中間件的時候,我們也可以手動實現這兩個功能。

2、HTTP 方法

gin.Engine 支持配置 HTTP 多個方法,比如 GET、POST、PUT、DELETE 等。

以第一篇筆記中的代碼為例,其設置方法如下:

r.GET("/test", TestHandler)
r.POST("/test", TestHandler)
r.PUT("/test", TestHandler)
r.DELETE("/test", TestHandler)

3、路由分組與中間件

除了設置單個路由,我們還可以對路由進行分組設置,比如需要控制版本,或者模塊設置需要統一的前綴,又或者是需要統一設置中間件功能的時候。

其整體代碼示例如下:

package main

import (
    "fmt"
    "net/http"
    "github.com/gin-gonic/gin"
)

type TestResponse struct {
    Code    int    `json:"code"`
    Message string `json:"message"`
}

func TestHandler(c *gin.Context) {
    response := TestResponse{
        Code:    0,
        Message: "success",
    }
    c.JSON(http.StatusOK, response)
}

func main() {
    r := gin.Default()

    v1 := r.Group("/v1")
    {
        v1.GET("/test", TestHandler)
    }

    err := r.Run(":9898")
    if err != nil {
        fmt.Println("gin run in 9898 error:", err)
    }
}

這裏,我們設置了一個路由名稱以 v1 為前綴的路由組,其下每個路由的訪問都需要帶有 /v1,這樣就實現了統一設置路由前綴的功能。

而如果我們需要向其中添加中間件的時候,也可以不用挨個路由進行設置,而是在 v1 路由組的設置中就可以實現,比如:

v1 := r.Group("/v1", Middleware1, Middleware2)

這樣,其下每個路由的 handler 函數在調用前就都會先調用 Middleware1Middleware2 這兩個中間件。

以上就是本篇筆記關於 gin.Engine 的全部內容,其實中間件的相關操作也應該屬於 gin.Engine 的內容,但是那部分需要介紹的知識點和想要用於介紹的代碼示例略多,所以就單獨開一篇筆記在後面再介紹。

user avatar xiaoweiyu 頭像 FatTiger4399 頭像 13917911249 頭像 cyningsun 頭像 pudongping 頭像 gouguoyin 頭像 yinggaozhen 頭像 zilliz 頭像 tingtr 頭像 TwilightLemon 頭像 fedl 頭像 dadegongjian 頭像
46 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.