動態

詳情 返回 返回

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 ljc1212 頭像 ayuan01 頭像 u_16281588 頭像 motianlun_5d0766992e67a 頭像 yian 頭像 zhuyundataflux 頭像 wuliaodeliema 頭像 yunpan-plus 頭像 aigoto 頭像 dbkangaroo 頭像 gqkmiss 頭像 algieba 頭像
點贊 33 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.