一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Go Fiber 框架系列教程 03:中間件

 風聲之家 2021-10-18

2021-10-18

閱讀本文大概需要 10 分鐘。

大家好,我是 polarisxu。

Middleware(中間件) 是一個 Web 框架重要的組成部分,通過這種模式,可以方便的擴展框架的功能。目前 Go Web 框架都提供了 Middleware 的功能,也有眾多可用的 Middleware。

Fiber 也是如此,官方提供了眾多的 Middleware,方便用戶直接使用。本文先看看 Fiber 中 Middleware 的定義,然后介紹 Fiber 中的幾個 Middleware,最后自己實現(xiàn)一個 Middleware。

Fiber 文檔中關于 Middleware 的說明:中間件是在 HTTP 請求周期中鏈接的函數(shù),它可以訪問用于執(zhí)行特定操作(例如,記錄每個請求或啟用 CORS)的上下文。

01 Middleware 長什么樣

設計用于更改請求或響應的函數(shù)稱為中間件函數(shù)。Next 是 Fiber 路由器函數(shù),當它被調(diào)用時,執(zhí)行與當前路由匹配的下一個函數(shù)。

可見,中間件其實和 Handler 是一樣的,只是用途有區(qū)別?;蛘哒f至少簽名是一樣的,這樣才能更好的形成一個鏈。

因此,F(xiàn)iber 中的中間件簽名如下:

func(ctx *fiber.Ctx) error

Fiber 沒有專門定義中間件類型。

此外,從 fiber.App.Use 方法也可以看到,中間件和普通的 Handler 并無本質不同。

// Use registers a middleware route that will match requests
// with the provided prefix (which is optional and defaults to "/").
//
//  app.Use(func(c *fiber.Ctx) error {
//       return c.Next()
//  })
//  app.Use("/api", func(c *fiber.Ctx) error {
//       return c.Next()
//  })
//  app.Use("/api", handler, func(c *fiber.Ctx) error {
//       return c.Next()
//  })
//
// This method will match all HTTP verbs: GET, POST, PUT, HEAD etc...
func (app *App) Use(args ...interface{}) Router {
 var prefix string
 var handlers []Handler

 for i := 0; i < len(args); i++ {
  switch arg := args[i].(type) {
  case string:
   prefix = arg
  case Handler:
   handlers = append(handlers, arg)
  default:
   panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf(arg)))
  }
 }
 app.register(methodUse, prefix, handlers...)
 return app
}

而 fiber.Handler 類型只是 func(*fiber.Ctx) error 的別名:

// Handler defines a function to serve HTTP requests.
type Handler = func(*Ctx) error

這點上,Gin 框架和 Fiber 是類似的。不過,有一些框架,比如 Echo,專門定義了中間件類型。但不管怎么樣,中間件的本質和普通路由 Handler 是類似的。

02 Fiber 內(nèi)置的中間件

所有內(nèi)置的中間件可以在 fiber 項目的 middleware 子包找到,這些中間件對應的文檔在這里:https://docs./api/middleware。

以 Recover 中間件為例,看看官方中間件的實現(xiàn)方法,我們自己的中間件可以參照實現(xiàn)。

1)簽名

func New(config ...Config) fiber.Handler

上文說了,中間件就是一個 Handler,因此這里 New 函數(shù)返回 fiber.Handler,這就中間件。

至于 New 函數(shù)的參數(shù)不做任何要求,只需要最終返回 fiber.Handler 即可。

2)配置

一個好的中間件,或通用的中間件,一般都會有配置,讓中間件更靈活、更強大??纯?Recover 的配置定義:

// Config defines the config for middleware.
type Config struct {
    // Next defines a function to skip this middleware when returned true.
    //
    // Optional. Default: nil
    Next func(c *fiber.Ctx) bool

    // EnableStackTrace enables handling stack trace
    //
    // Optional. Default: false
    EnableStackTrace bool

    // StackTraceHandler defines a function to handle stack trace
    //
    // Optional. Default: defaultStackTraceHandler
    StackTraceHandler func(e interface{})
}

具體配置是什么樣的,需要根據(jù)中間件的功能來定義。

不過,配置中 Next 這個行為,很多中間件都可以有。

3)默認配置

一般的,會提供一個默認配置,方便使用。而且,大部分時候,使用默認配置即可。Recover 的默認配置如下:

var ConfigDefault = Config{
    Next:              nil,
    EnableStackTrace:  false,
    StackTraceHandler: defaultStackTraceHandler,
}

如果這樣調(diào)用 recover.New() ,會默認使用上面的默認配置。

最后看看 New 函數(shù)的代碼:

// New creates a new middleware handler
func New(config ...Config) fiber.Handler {
 // Set default config
 cfg := configDefault(config...)

 // Return new handler
 return func(c *fiber.Ctx) (err error) {
  // Don't execute middleware if Next returns true
  if cfg.Next != nil && cfg.Next(c) {
   return c.Next()
  }

  // Catch panics
  defer func() {
   if r := recover(); r != nil {
    if cfg.EnableStackTrace {
     cfg.StackTraceHandler(r)
    }

    var ok bool
    if err, ok = r.(error); !ok {
     // Set error that will call the global error handler
     err = fmt.Errorf("%v", r)
    }
   }
  }()

  // Return err if exist, else move to next handler
  return c.Next()
 }
}

以上就是一個 Fiber 標準中間件的寫法。

具體使用時就是:app.Use(recover.New())。

當然,如果只是自己項目使用,可以不用寫配置。

03 實現(xiàn)一個簡單的中間件

通過 Recover 學習到了中間件的標準寫法,如果中間件只在自己項目使用,不需要靈活性,完全可以采用簡單的寫法。

func Security(ctx *fiber.Ctx) error {
  ctx.Set("X-XSS-Protection""1; mode=block")
  ctx.Set("X-Content-Type-Options""nosniff")
  ctx.Set("X-Download-Options""noopen")
  ctx.Set("Strict-Transport-Security""max-age=5184000")
  ctx.Set("X-Frame-Options""SAMEORIGIN")
  ctx.Set("X-DNS-Prefetch-Control""off")

  // 執(zhí)行下一個 Handler
  return ctx.Next()
}

這其實也是一個 Handler,對吧。無非最后調(diào)用的是 ctx.Next,而不是 ctx.JSON 之類的。

使用時這樣:

app := fiber.New()
app.Use(Security)

只要理解中間件的機制,不需要拘泥于具體形式,可以靈活變換中間件的寫法。

04 總結

本文講解了什么是中間件,F(xiàn)iber 中間件長什么樣以及對內(nèi)置中間件 Recover 的學習,最后自己實現(xiàn)一個簡單的中間件。掌握了 Fiber 的中間件,相信對其他 Go Web 框架的中間件的學習也就不難了,因為都差不多。



    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩一区二区三区在线日| 黄片免费观看一区二区| 欧美欧美欧美欧美一区| 国产在线一区二区三区不卡| 久久精品色妇熟妇丰满人妻91| 在线免费国产一区二区三区| 九九九热在线免费视频| 婷婷色网视频在线播放| 午夜久久精品福利视频| 免费在线播放不卡视频| 亚洲第一区二区三区女厕偷拍| 91欧美日韩一区人妻少妇| 好东西一起分享老鸭窝| 日韩成人高清免费在线| 午夜亚洲精品理论片在线观看| 色婷婷国产熟妇人妻露脸| 日本美国三级黄色aa| 又色又爽又无遮挡的视频| 国产午夜精品亚洲精品国产| 亚洲国产av在线视频| 韩日黄片在线免费观看| 免费在线播放一区二区| 亚洲一区精品二人人爽久久| 亚洲性生活一区二区三区| 一区二区欧美另类稀缺| 日韩欧美精品一区二区三区| 日韩偷拍精品一区二区三区| 五月婷婷亚洲综合一区| 一个人的久久精彩视频| 东京热男人的天堂一二三区| 成人日韩视频中文字幕| 在线免费观看黄色美女| 国产精品一区二区日韩新区| 欧美乱码精品一区二区三| 亚洲欧洲一区二区综合精品| 一区二区三区人妻在线| 久草国产精品一区二区| 九九热精品视频免费观看| 日韩精品毛片视频免费看| 日韩国产亚洲一区二区三区| 伊人网免费在线观看高清版|