Go言語のGinフレームワーク[ミドルウェア]集 (7)

ミドルウェアとは何ですか?

Gin フレームワークは、Web アプリケーションを構築するための Go 言語フレームワークです。ミドルウェアは、Gin フレームワークにおける重要な概念であり、リクエスト処理中に追加の機能や処理ロジックを追加するために使用されます。

Gin フレームワークのミドルウェアは、リクエストの処理前または処理後にいくつかの操作を実行できます。通常、ミドルウェアはリクエストの検証、ロギング、エラー処理、その他の機能を処理するために使用されます。Gin フレームワークは、ミドルウェアを定義して使用するためのシンプルかつ柔軟な方法を提供します。

ミドルウェアの原則?

Gin フレームワークのミドルウェア原理は、次のように簡単に要約できます。関数ラッパーを通じて、ミドルウェア関数がリクエスト処理チェーンに組み込まれ、リクエストの処理前または処理後にいくつかの追加機能を実行します。

Gin フレームワークのミドルウェアは、次のような特徴を持つ機能です。

  1. 関数シグネチャ: ミドルウェア関数のシグネチャはfunc(c *gin.Context)*gin.Contextリクエスト コンテキストを示す型パラメータを受け入れます。

  2. 実行順序:ミドルウェア機能は登録順に実行されます。リクエストが処理される前は、プレミドルウェアが登録された順序で実行され、リクエストが処理された後は、ポストミドルウェアが逆の順序で実行されます。

  3. リクエスト処理チェーン: Jin フレームワークはリクエスト処理チェーンを維持し、登録されたミドルウェア機能を処理チェーン内のリンクに順番にパッケージ化します。各リンクは、リクエストの処理前または処理後にいくつかの操作を実行できます。

  4. コンテキストの受け渡し: ミドルウェア関数は、リクエスト コンテキスト内のデータにアクセスして変更できます。Gin フレームワークは*gin.Contextオブジェクトを使用してリクエスト コンテキストを表し、ミドルウェア関数はこのオブジェクトを使用してリクエスト情報の取得、応答情報の設定などを行うことができます。

package main

import (
	"20230615/routers"
	"fmt"
	"time"

	"github.com/gin-gonic/gin"
)

// 定义一个 userinfo 表单结构体对象
type UserInfo struct {
	UserName string `json:"username" form:"username"`
	Password string `json:"password" form:"password"`
	Age      string `json:"age" form:"age"`
}

// 路由中间件 在路由中走的 initMiddleWares
func initMiddleWares(c *gin.Context) {
	start := time.Now().UnixNano()
	fmt.Println("init middleware----路由-中间件----1", start)
	// c.Next()它在调用处理程序内部执行链中的挂起处理程序。Next只能在中间件内部使用
	c.Next()
	end := time.Now().UnixNano()
	fmt.Println("init middleware----路由-中间件----2", end)
}
func main() {
	// 定义一个路由引擎对象
	router := gin.Default()
	// 加载 渲染模板 全局
	router.LoadHTMLGlob("*templates/**/*")
	// 路由 get请求后 返回数据到模板渲染
	router.GET("/", initMiddleWares, func(c *gin.Context) {
		fmt.Println("------页面首页--------")
		c.String(200, "message")
	})

	routers.LoginRouterInit(router) // init router 初始化路由包

	router.Run(":8080")
}

出力結果:

init middleware----路由-中间件----1 1687681850770421700
------页面首页--------
init middleware----路由-中间件----2 1687681850771422200

ここでの特徴は、プログラムを一時停止して実行を継続できるようにするための Next() メソッドがミドルウェア内に追加されていることです。

Ctrl キーを押しながらマウスの左ボタンをクリックすると、ソース コードに戻ってコードの他のメソッドを表示できます。Abort () メソッド: Abort により、保留中のハンドラーが呼び出されないようにすることができます。これによって現在のハンドラーは停止されないことに注意してください。

package main

import (
	"20230615/routers"
	"fmt"
	"time"

	"github.com/gin-gonic/gin"
)

// 定义一个 userinfo 表单结构体对象
type UserInfo struct {
	UserName string `json:"username" form:"username"`
	Password string `json:"password" form:"password"`
	Age      string `json:"age" form:"age"`
}

// 路由中间件 在路由中走的 initMiddleWares
func initMiddleWares(c *gin.Context) {
	start := time.Now().UnixNano()
	fmt.Println("init middleware----路由-中间件----1", start)
	// // c.Next()它在调用处理程序内部执行链中的挂起处理程序。Next只能在中间件内部使用
	// c.Next()
	// Abort可防止调用挂起的处理程序。请注意,这不会停止当前处理程序。
	c.Abort()
	end := time.Now().UnixNano()
	fmt.Println("init middleware----路由-中间件----2", end)
}
func main() {
	// 定义一个路由引擎对象
	router := gin.Default()
	// 加载 渲染模板 全局
	router.LoadHTMLGlob("*templates/**/*")
	// 路由 get请求后 返回数据到模板渲染
	router.GET("/", initMiddleWares, func(c *gin.Context) {
		fmt.Println("------页面首页--------")
		c.String(200, "message")
	})

	routers.LoginRouterInit(router) // init router 初始化路由包

	router.Run(":8080")
}

出力:

init middleware----路由-中间件----1 1687684669762450500
init middleware----路由-中间件----2 1687684669762450500

もちろん、デモは私たちが使用するいくつかの単純かつ一時的なメソッドにすぎません。内部メソッドは多数あるため、1 つずつ説明しません。メソッドの使用方法は自分で確認でき、トレースバック コード スニペットを表示できます。 。

グローバルミドルウェアコードのデモンストレーション:

func initMiddlewareOne(ctx *gin.Context) {
	fmt.Println("-one-中间件-initMiddlewareOne--1")
	// Next() 方法 调用该请求的剩余程序
	ctx.Next()
	fmt.Println("-one-中间件-initMiddlewareOne--2")

}
func initMiddlewareTwo(ctx *gin.Context) {
	fmt.Println("-two--中间件--initMiddlewareTwo--1")
	//终止调用该程序的剩余请求处理程序 abort()方法
	// ctx.Abort()
	ctx.Next()
	fmt.Println("-two--中间件--initMiddlewareTwo--2")
}


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

	r.SetFuncMap(template.FuncMap{
		"UnitTime": UnitTime,
	})

	r.LoadHTMLGlob("*templates/**/*")

	r.Static("/static", "./static")

	// 通过 use() 方法全局注册中间件
	// r.Use(initMiddlewareOne, initMiddlewareTwo)



	r.GET("/", func(ctx *gin.Context) {
		fmt.Println("这是一个首页")
		ctx.HTML(http.StatusOK, "default/news.html", gin.H{
			"title": "这个是一个首页",
		})
		// ctx.String(200, "这是一个首页")
	})

	// 抽离了 路由,传入了 r;这样就是注册了路由,同时简化了入口文件的大小
	routers.DefaultRoutersInit(r)
	// 登陆路由 抽离 下一步,给路由内部的方法抽离成一个 控制器 controllers
	routers.LoginRoutersinit(r)

	r.Run(":8001")

}

端子出力:

// 中间件内部都是next方法
-one-中间件-initMiddlewareOne--1
-two--中间件--initMiddlewareTwo--1
-one-中间件-initMiddlewareOne--1
 -two--中间件--initMiddlewareTwo--2
-one-中间件-initMiddlewareOne--2
 -two--中间件--initMiddlewareTwo--2
 -one-中间件-initMiddlewareOne--2

上記は main.go メイン エントリ ファイルで使用されるルーティング ミドルウェアのデモですが、ルーティング ミドルウェアを initmiddlewares で抽出するにはどうすればよいでしょうか?

作成したミドルウェアinit.goファイルをカレントルートに登録するにはどうすればよいでしょうか? 

package middlewares

import (
	"fmt"

	"github.com/gin-gonic/gin"
)

// 方法想要其他包也可以引用,必须要让
func InitMiddlewares(c *gin.Context) {
	url := c.Request.URL.String()

	fmt.Println("路由分组--中间件---", url)
}

パッケージ/ミドルウェアをルートに直接導入する

具体的な利用方法は以下の通りです。

package routers

import (
	"github.com/gin-gonic/gin"

	"20230619/controllers/login"
	"20230619/middlewares"
)

// 1. 如果我们要全局gold 使用,那么方法的首字母一定是大写
// 2. 路由内部的处理方法 进行抽离 使其成一个控制器 controller 「 首先, 」
func LoginRoutersinit(r *gin.Engine) {
	loginRouters := r.Group("/login", middlewares.InitMiddlewares)
	{
		loginRouters.GET("/", login.LoginControllers{}.Index)
		loginRouters.GET("/edit", login.LoginControllers{}.Edit)

	}
}

Gin フレームワーク ミドルウェアの一般的な操作のいくつかは次のとおりです。

ミドルウェアの登録: Gin フレームワークでは、Use メソッドを呼び出すことでミドルウェアを登録できます。たとえば、router.Use(middleware1, middleware2) のようになります。

グローバルミドルウェア:ルーターにミドルウェアを登録することで、すべてのリクエストに適用できます。たとえば、router.Use(globalMiddleware)。

注: ここを拡張すると、ルーティング エンジンを定義するには 2 つの方法があり、1 つは New() とdefault() です。デフォルト モードを使用してルーティング エンジンを作成することをお勧めします (この方法では、デフォルトのルーティング エンジンは Logger を使用します)およびReveryミドルウェア)。

同時に、これら 2 つのミドルウェアは異なる機能を持っています。

         ロガーミドルウェアは、GIN_MODE=release で構成された gin.DefaultWriter にログを書き込みます。

         回復ミドルウェアがパニックを回復します。パニックが発生した場合、ステータス コード値 500 が書き込まれます。

ただし、 new() メソッドを使用してルーティング エンジンを作成することは、ミドルウェアを使用しないまったく新しいものです。それはソースコードで確認できます。

 

 

ルートレベルミドルウェア:各ルートのハンドラ関数にミドルウェアを登録できます。たとえば、router.GET("/api"、routeMiddleware、handleFunc) です。

ミドルウェア メソッドを定義した後、それをルートに直接配置すると、このルートでのみ有効になります。

 

グループレベルのミドルウェア: ミドルウェアをルーティング グループに登録して、グループ内のすべてのルートに適用できます。たとえば、apiGroup := router.Group("/api", groupMiddleware)。

コンテキスト ミドルウェア: ミドルウェアは、リクエスト コンテキスト内のデータにアクセスして変更できます。たとえば、ユーザーを認証し、後続の処理機能で使用できるようにユーザー情報をコンテキストに保存します。

エラー処理ミドルウェア: リクエスト処理中にエラーをキャプチャして処理するミドルウェアを定義できます。たとえば、エラーをログに記録したり、特定のエラー応答を返したりします。

チェーンミドルウェア: 複数のミドルウェアを接続してミドルウェアチェーンを形成できます。たとえば、router.Use(middleware1, middleware2, middleware3) のようになります。

一般に、ミドルウェアは、Gin フレームワークの非常に便利な機能であり、開発者がさまざまな共通機能と処理ロジックを実装するのに役立ち、コードをよりモジュール化して保守しやすくします。

あなたの勉強のお役に立てれば幸いです!

おすすめ

転載: blog.csdn.net/A_LWIEUI_Learn/article/details/131379589