golang

Golang(Ginフレームワーク)のミドルウェアの使い方、複数使うときの適用の順番の決め方

この記事は、Golang(Ginフレームワーク)でのミドルウェアの使い方の忘備録です。

何か間違いがあれば、コメントを頂ければ幸いです。

ここでは

  • 全てのルートに適用
  • ルートのグループに対して適用
  • 1つのルートにのみ適用

の3つの場合について説明します。

全てのルートに適用する場合

main.goファイルで以下のように、r.Use(ミドルウェア1, ミドルウェア2, ...) と書けばいいです。

ここで説明の都合上、ミドルウェア関数( Middleware1(), Middleware2() )をmain.goファイル内に書いて定義していますが、

普通は別にミドルウェア用のフォルダを作り、

その中のgoファイル(例えば middlewares/Middleware1.go)で定義するべきでしょう。

package main

import(
   //とっても大事だけど省略
)

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

   r.Use(Middleware1, Middleware2)

   //複数のルート
   r.GET("/hello", func(c *gin.Context) {
      fmt.Println("root handler")
      c.String(http.StatusOK, "Hello")
   })

   r.GET("/world", func(c *gin.Context) {
      fmt.Println("root handler")
      c.String(http.StatusOK, "World")
    })

    r.Run(":8080")
}

Middleware1 := func(c *gin.Context) {
      // リクエストの前処理として例えば"middleware1 before handler"って言う
      fmt.Println("middleware1 before handler")

      // 次のミドルウェア、またはルートハンドラ関数に処理を移す
      c.Next()

   // レスポンスの後処理
      fmt.Println("middleware1 after handler")
}

Middleware2 := func(c *gin.Context) {
   // リクエストの前処理
      fmt.Println("middleware1 before handler")

      // 次のミドルウェア、またはルートハンドラ関数に処理を移す
      c.Next()

   // レスポンスの後処理
      fmt.Println("middleware1 after handler")
}

go run main.goなどのコマンドで上記のコードを実行し、ブラウザから http://localhost:8080/helloにアクセスすると、

ブラウザには"Hello"と表示され、ターミナルには以下のような順番の表示があるはずです。

middleware1 before handler
middleware2 before handler
root handler
middleware2 after handler
middleware1 after handler

http://localhost:8080/world にアクセスした場合も同様です。

また、ミドルウェア関数が3つ以上の際も同様です。

1つのルートにのみ適用

main.goファイルで以下のように、

r.GET( URL文字列 ,ミドルウェア1, ミドルウェア2, ... , ルートハンドラ関数)

と書けばいいです。

適用される順番は、 r.GET()に書いた順番の通りになります。

package main

import(
   //とっても大事だけど省略
)

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

   //複数のルート
   r.GET("/hello", Middleware1, Middleware2, func(c *gin.Context) {
    fmt.Println("root handler")
        c.String(http.StatusOK, "Hello")
   })

   r.GET("/world", func(c *gin.Context) {
    fmt.Println("root handler")
        c.String(http.StatusOK, "World")
    })

    r.Run(":8080")
}

Middleware1 := func(c *gin.Context) {
   fmt.Println("middleware1 before handler")

     c.Next()

   fmt.Println("middleware1 after handler")
}

Middleware2 := func(c *gin.Context) {
   fmt.Println("middleware2 before handler")

     c.Next()

   fmt.Println("middleware2 after handler")
}

ブラウザから http://localhost:8080/helloにアクセスすると、ターミナルに「全てのルートに対して適用」にあったのと同様の表示があるはずです。また、http://localhost:8080/worldにアクセスすると、ミドルウェアは適用されず、"root handler"とだけ表示されます。

ルートのグループに対して適用

以下のように

g := r.Group("/group", Middleware1, Middleware2) { }

という風に、ルートのグループのURLに続けてミドルウェアを並べればいいです。

package main

import (
    //とっても大事だけど省略
)

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

    // グループを作成し、ミドルウェアを適用する
    g := r.Group("/group", Middleware1, Middleware2)
    {
    // 上で "g" としましたので!!!!!
        g.GET("/hello", func(c *gin.Context) {
        fmt.Println("root handler")
           c.String(http.StatusOK, "Hello")
        })

        g.GET("/world", func(c *gin.Context) {
        fmt.Println("root handler")
           c.String(http.StatusOK, "World")
        })
    }

    r.Run(":8080")
}

Middleware1 := func(c *gin.Context) {
   fmt.Println("middleware1 before handler")

     c.Next()

   fmt.Println("middleware1 after handler")
}

Middleware2 := func(c *gin.Context) {
   fmt.Println("middleware2 before handler")

     c.Next()

   fmt.Println("middleware2 after handler")
}

ブラウザから http://localhost:8080/group/helloにアクセスすると、ターミナルに「全てのルートに対して適用」にあったのと同様の表示があるはずです。

-golang
-, , ,