文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Go Fiber 框架系列:中间件

2024-12-02 20:11

关注

大家好,我是 polarisxu。

Middleware(中间件) 是一个 Web 框架重要的组成部分,通过这种模式,可以方便的扩展框架的功能。目前 Go Web 框架都提供了 Middleware 的功能,也有众多可用的 Middleware。

Fiber 也是如此,官方提供了众多的 Middleware,方便用户直接使用。本文先看看 Fiber 中 Middleware 的定义,然后介绍 Fiber 中的几个 Middleware,最后自己实现一个 Middleware。

Fiber 文档中关于 Middleware 的说明:中间件是在 HTTP 请求周期中链接的函数,它可以访问用于执行特定操作(例如,记录每个请求或启用 CORS)的上下文。

01 Middleware 长什么样

设计用于更改请求或响应的函数称为中间件函数。Next 是 Fiber 路由器函数,当它被调用时,执行与当前路由匹配的下一个函数。

可见,中间件其实和 Handler 是一样的,只是用途有区别。或者说至少签名是一样的,这样才能更好的形成一个链。

因此,Fiber 中的中间件签名如下:

  1. func(ctx *fiber.Ctx) error 

Fiber 没有专门定义中间件类型。

此外,从 fiber.App.Use 方法也可以看到,中间件和普通的 Handler 并无本质不同。

  1. // Use registers a middleware route that will match requests 
  2. // with the provided prefix (which is optional and defaults to "/"). 
  3. // 
  4. //  app.Use(func(c *fiber.Ctx) error { 
  5. //       return c.Next() 
  6. //  }) 
  7. //  app.Use("/api", func(c *fiber.Ctx) error { 
  8. //       return c.Next() 
  9. //  }) 
  10. //  app.Use("/api", handler, func(c *fiber.Ctx) error { 
  11. //       return c.Next() 
  12. //  }) 
  13. // 
  14. // This method will match all HTTP verbs: GET, POST, PUT, HEAD etc... 
  15. func (app *App) Use(args ...interface{}) Router { 
  16.  var prefix string 
  17.  var handlers []Handler 
  18.  
  19.  for i := 0; i < len(args); i++ { 
  20.   switch arg := args[i].(type) { 
  21.   case string: 
  22.    prefix = arg 
  23.   case Handler: 
  24.    handlers = append(handlers, arg) 
  25.   default
  26.    panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf(arg))) 
  27.   } 
  28.  } 
  29.  app.register(methodUse, prefix, handlers...) 
  30.  return app 

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

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

这点上,Gin 框架和 Fiber 是类似的。不过,有一些框架,比如 Echo,专门定义了中间件类型。但不管怎么样,中间件的本质和普通路由 Handler 是类似的。

02 Fiber 内置的中间件

所有内置的中间件可以在 fiber 项目的 middleware 子包找到,这些中间件对应的文档在这里:https://docs.gofiber.io/api/middleware。

以 Recover 中间件为例,看看官方中间件的实现方法,我们自己的中间件可以参照实现。

1)签名

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

上文说了,中间件就是一个 Handler,因此这里 New 函数返回 fiber.Handler,这就中间件。

至于 New 函数的参数不做任何要求,只需要最终返回 fiber.Handler 即可。

2)配置

一个好的中间件,或通用的中间件,一般都会有配置,让中间件更灵活、更强大。看看 Recover 的配置定义:

  1. // Config defines the config for middleware. 
  2. type Config struct { 
  3.     // Next defines a function to skip this middleware when returned true
  4.     // 
  5.     // Optional. Default: nil 
  6.     Next func(c *fiber.Ctx) bool 
  7.  
  8.     // EnableStackTrace enables handling stack trace 
  9.     // 
  10.     // Optional. Defaultfalse 
  11.     EnableStackTrace bool 
  12.  
  13.     // StackTraceHandler defines a function to handle stack trace 
  14.     // 
  15.     // Optional. Default: defaultStackTraceHandler 
  16.     StackTraceHandler func(e interface{}) 

具体配置是什么样的,需要根据中间件的功能来定义。

不过,配置中 Next 这个行为,很多中间件都可以有。

3)默认配置

一般的,会提供一个默认配置,方便使用。而且,大部分时候,使用默认配置即可。Recover 的默认配置如下:

  1. var ConfigDefault = Config{ 
  2.     Next:              nil, 
  3.     EnableStackTrace:  false
  4.     StackTraceHandler: defaultStackTraceHandler, 

如果这样调用 recover.New() ,会默认使用上面的默认配置。

最后看看 New 函数的代码:

  1. // New creates a new middleware handler 
  2. func New(config ...Config) fiber.Handler { 
  3.  // Set default config 
  4.  cfg := configDefault(config...) 
  5.  
  6.  // Return new handler 
  7.  return func(c *fiber.Ctx) (err error) { 
  8.   // Don't execute middleware if Next returns true 
  9.   if cfg.Next != nil && cfg.Next(c) { 
  10.    return c.Next() 
  11.   } 
  12.  
  13.   // Catch panics 
  14.   defer func() { 
  15.    if r := recover(); r != nil { 
  16.     if cfg.EnableStackTrace { 
  17.      cfg.StackTraceHandler(r) 
  18.     } 
  19.  
  20.     var ok bool 
  21.     if err, ok = r.(error); !ok { 
  22.      // Set error that will call the global error handler 
  23.      err = fmt.Errorf("%v", r) 
  24.     } 
  25.    } 
  26.   }() 
  27.  
  28.   // Return err if exist, else move to next handler 
  29.   return c.Next() 
  30.  } 

以上就是一个 Fiber 标准中间件的写法。

具体使用时就是:app.Use(recover.New())。

当然,如果只是自己项目使用,可以不用写配置。

03 实现一个简单的中间件

通过 Recover 学习到了中间件的标准写法,如果中间件只在自己项目使用,不需要灵活性,完全可以采用简单的写法。

  1. func Security(ctx *fiber.Ctx) error { 
  2.   ctx.Set("X-XSS-Protection""1; mode=block"
  3.   ctx.Set("X-Content-Type-Options""nosniff"
  4.   ctx.Set("X-Download-Options""noopen"
  5.   ctx.Set("Strict-Transport-Security""max-age=5184000"
  6.   ctx.Set("X-Frame-Options""SAMEORIGIN"
  7.   ctx.Set("X-DNS-Prefetch-Control""off"
  8.  
  9.   // 执行下一个 Handler 
  10.   return ctx.Next() 

这其实也是一个 Handler,对吧。无非最后调用的是 ctx.Next,而不是 ctx.JSON 之类的。

使用时这样:

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

只要理解中间件的机制,不需要拘泥于具体形式,可以灵活变换中间件的写法。

04 总结

 

本文讲解了什么是中间件,Fiber 中间件长什么样以及对内置中间件 Recover 的学习,最后自己实现一个简单的中间件。掌握了 Fiber 的中间件,相信对其他 Go Web 框架的中间件的学习也就不难了,因为都差不多。

 

来源:polarisxu内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯