专栏首页飞雪无情的博客Go 语言 | 1.16 新增的embed在各流行Web框架中的应用

Go 语言 | 1.16 新增的embed在各流行Web框架中的应用

什么是 Go embed

在前几天刚发布的Golang 1.16版本中,新增了一个大家期待已久的特性//go:embed,它的作用就是可以在Go语言应用程序中包含任何文件、目录的内容,也就是说我们可以把文件以及目录中的内容都打包到生成的Go语言应用程序中了,部署的时候,直接扔一个二进制文件就可以了,不用再包含一些静态文件了,因为它们已经被打包到生成的应用程序中了。

embed 的基本用法

Go embed的使用非常简单,通过//go:embed指令即可,下面我通过一个例子说明:

package main
import (
   "embed"
   "fmt"
)
//go:embed fire
var s string
//go:embed fire
var b []byte
//go:embed templates
var fs embed.FS
func main() {
   fmt.Println(s)
   fmt.Println(string(b))
   data, err := fs.ReadFile("templates/index.tmpl")
   fmt.Println(err,string(data))
}

以上代码中,主要是通过//go:embed指令达到读取文件内容的目的。//go:embed指令后可以是一个文件,也可以是多个文件(空格隔开即可),也可以是一个目录。 其中string[]byte类型都只能匹配一个文件,如果要匹配多个文件或者一个目录,就要使用embed.FS类型。

特别注意:embed这个包一定要导入,如果导入不使用的话,使用 _ 导入即可。

embed 在http web中的使用

看到embed这个功能,你首先想到的应该是把以前开发Web应用时使用的静态文件、模板文件打包进应用程序中,所以接下来就来看下embed如何在http web中使用。

下面先来看一个使用http托管静态文件的示例

package main
import (
   "embed"
   "net/http"
)
//go:embed static
var static embed.FS
func main() {
   http.ListenAndServe(":8080", http.FileServer(http.FS(static)))
}

看到了吧就是这么简单,就是这么魔幻,几行代码就实现了静态文件的Web托管,并且可以结合embed特性把静态static目录里的内容全部打包到生成的应用程序中,部署非常方便。 以上代码的核心除了//go:embed指令外,还有通过http.FS这个函数,把embed.FS类型的static转换为http.FileServer函数可以识别的http.FileSystem类型。

embed 在模板中的应用

在Go Web的开发中,除了静态文件外,还有Go Template,可以更好的帮助我们渲染Web网页。下面来下看embed是如何被Go 模板使用的。

package main
import (
   "embed"
   "html/template"
   "net/http"
)
//go:embed templates
var tmpl embed.FS
func main() {
   t, _ := template.ParseFS(tmpl, "templates/*.tmpl")
   http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
      t.ExecuteTemplate(rw,"index.tmpl",map[string]string{"title":"Golang Embed 测试"})
   })
   http.ListenAndServe(":8080",nil)
}

从以上示例中可以看到,template包提供了ParseFS函数,可以直接从一个embed.FS中加载模板,然后用于HTTP Web中。模板文件夹的结构如下所示:

templates
└── index.tmpl

Gin 框架

Gin是一个非常流行的框架,它对于静态文件以及HTML模板支持的也非常好,现在我们来看下它和embed如何结合使用。

Gin静态文件服务

Gin框架中托管一个静态文件服务非常简单,使用Static方法即可,下面看个例子:

package main
import (
   "embed"
   "github.com/gin-gonic/gin"
   "net/http"
)
//go:embed static
var static embed.FS
func main() {
   r:=gin.Default()
   r.StaticFS("/",http.FS(static))
   r.Run(":8080")
}

从以上示例中可以看到,在Gin中使用embed作为静态文件,也是用过http.FS函数转化的。

Gin HTML 模板

同样的,embed也可以用于Gin的HTML模板中,示例如下:

package main
import (
   "embed"
   "github.com/gin-gonic/gin"
   "html/template"
)
//go:embed templates
var tmpl embed.FS
//go:embed static
var static embed.FS
func main() {
   r:=gin.Default()
   t, _ := template.ParseFS(tmpl, "templates/*.tmpl")
   r.SetHTMLTemplate(t)
   r.GET("/", func(ctx *gin.Context) {
      ctx.HTML(200,"index.tmpl",gin.H{"title":"Golang Embed 测试"})
   })
   r.Run(":8080")
}

和前面的模板例子一样,也是通过template.ParseFS函数先加载embed中的模板,然后通过Gin的SetHTMLTemplate设置后就可以使用了。

Fiber

在Fiber中要使用embed托管一个静态文件服务,需要使用它的FileSystem,看如下示例。

package main
import (
   "embed"
   "github.com/gofiber/fiber/v2"
   "github.com/gofiber/fiber/v2/middleware/filesystem"
   "net/http"
)
//go:embed templates
var tmpl embed.FS
//go:embed static
var static embed.FS
func main() {
   app := fiber.New()
   app.Use("/", filesystem.New(filesystem.Config{
      Root: http.FS(static),
   }))
   app.Listen(":3000")
}

同样的也是使用http.FS函数,然后结合fiber提供的filesystem达到静态托管文件服务的目的。

运行这段程序,然后在浏览器中输入http://127.0.0.1:3000/static/index.html即可看到效果。

搞定了静态文件托管,那么Fiber HTML模板也就比较容易了,代码如下所示:

package main
import (
   "embed"
   "github.com/gofiber/fiber/v2"
   "github.com/gofiber/template/html"
   "net/http"
)
//go:embed templates
var tmpl embed.FS
func main() {
   engine := html.NewFileSystem(http.FS(tmpl), ".tmpl")
   app := fiber.New(fiber.Config{Views: engine})
   app.Get("/", func(ctx *fiber.Ctx) error {
      return ctx.Render("templates/index", fiber.Map{"title": "Golang Embed 测试"})
   })
   app.Listen(":3000")
}

通过html.NewFileSystem函数加载embed,然后把它当做视图渲染器,传给fiber.New即可,现在运行这个段代码,访问http://127.0.0.1:3000就可以看到模板渲染后的效果了。

小结

通过以上介绍,相信你肯定熟练的掌握了在各个框架中如何使用embed的了,其实我们可以总结下,会发现这个http.FS函数用的最多,因为它是一个把embed.FS转为http.FileSystem的工具函数,这样就可以在各个Web框架中直接使用。

本文为原创文章,转载注明出处,欢迎扫码关注公众号flysnow_org或者网站http://www.flysnow.org/,第一时间看后续精彩文章。觉得好的话,顺手分享到朋友圈吧,感谢支持。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Golang 1.16 新增 embed 包怎么使用?

    今天 Go 团队很高兴地宣布 Go 1.16 的发布,新增的 embed 包使用新的 //go:embed 指令提供对编译时访问嵌入的文件。

    frank.
  • 假期最后一天!Go1.16 重磅发布,新版本特性一览

    之前市面上已经有很多把今天文件嵌入golang二进制程序的工具了,这次golang官方将这一功能加入了embed标准库,从语言层面上提供了支持。。

    肉眼品世界
  • 解读Go语言的2020:变革前夜

    在作者去年年底撰写《解读 Go 语言的 2019》的时候,绝没有想到 2020 年将会如此的不平凡。全球范围内的疫情在大大地限制了人们和企业的对外活动之余,还带...

    深度学习与Python
  • 为什么我们从 Docker 转向了 Go?

    在以往的很多项目中,我们都采用了Docker,而且效果都很不错(大多数时候都不错,只不过有时我们的生产系统中的红帽系统文件会出一些莫名的状况,但可能并不是Doc...

    子润先生
  • Golang 1.16 中 Module 有什么变化?

    golang 1.16 默认开启 Modules,即使不存在 go.mod,Go 命令现在默认情况下也会在 module-aware(模块感知)模式下构建包。

    frank.
  • Go语言实践:从新手入门到上线真实的小型服务所遇到的那些坑

    Teamwork团队在去年写了近20万行Go代码,建造了一堆速度奇快的小型HTTP服务,本文列出了他们总结的9条经验教训。 为什么选择Go语言?Go语言,又称G...

    CSDN技术头条
  • Go语言实践:从新手入门到上线真实的小型服务所遇到的那些坑

    摘要: Teamwork团队在去年写了近20万行Go代码,建造了一堆速度奇快的小型HTTP服务,本文列出了他们总结的9条经验教训。 为什么选择Go语言?Go...

    李海彬
  • Go语言实践:从新手入门到上线真实的小型服务所遇到的那些坑

    摘要: Teamwork团队在去年写了近20万行Go代码,建造了一堆速度奇快的小型HTTP服务,本文列出了他们总结的9条经验教训。 为什么选择Go语言?Go...

    李海彬
  • Go语言实践:从新手入门到上线真实的小型服务所遇到的那些坑

    摘要: Teamwork团队在去年写了近20万行Go代码,建造了一堆速度奇快的小型HTTP服务,本文列出了他们总结的9条经验教训。 为什么选择Go语言?Go...

    李海彬

扫码关注云+社区

领取腾讯云代金券