The Go Language official maintenance team, rsc, previously proposed in the GitHub Issue to support Embedding files directly in the go command line. Files, I didn’t expect that in a few months, it was directly implemented, and in the 2021 go 1.16 version directly support embed package. With this feature, static files or project configuration files can be wrapped up directly, which makes deployment easier. Here’s how to use it officially.
embed package
See the official example directly:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package main
import (
"embed"
)
//go:embed hello.txt
var s string
//go:embed hello.txt
var b []byte
//go:embed hello.txt
var f embed.FS
func main() {
print(s)
print(string(b))
data, _ := f.ReadFile("hello.txt")
print(string(data))
}
|
You can see the keyword: go:embed
, through the annotation you can use the static file directly in the development of the above, in addition, you can also refer to multiple files or multiple directories:
1
2
3
4
5
6
7
8
|
package server
import "embed"
// content holds our static web server content.
//go:embed image/* template/*
//go:embed html/index.html
var content embed.FS
|
You can see that go:embed
supports multiple directories, single file or multiple files. If you don’t use embed.FS
, please add _
to the import, for example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package main
import _ "embed"
//go:embed hello.txt
var s string
//go:embed hello.txt
var b []byte
func main() {
print(s)
print(string(b))
}
|
With this Package, you no longer need a Third Party Package Resource Embedding , to see how to integrate the embed package into Gin?
Integrating Gin Framework
Let’s assume that Gin needs to contain static images and Template, the following is the directory structure:
1
2
3
4
5
6
7
8
9
10
11
|
├── assets
│ ├── favicon.ico
│ └── images
│ └── example.png
├── go.mod
├── go.sum
├── main.go
└── templates
├── foo
│ └── bar.tmpl
└── index.tmpl
|
How do I package Template and assets directories into Go? Look directly at main.go
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
package main
import (
"embed"
"html/template"
"net/http"
"github.com/gin-gonic/gin"
)
//go:embed assets/* templates/*
var f embed.FS
func main() {
router := gin.Default()
templ := template.Must(template.New("").ParseFS(f, "templates/*.tmpl", "templates/foo/*.tmpl"))
router.SetHTMLTemplate(templ)
// example: /public/assets/images/example.png
router.StaticFS("/public", http.FS(f))
router.GET("/", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"title": "Main website",
})
})
router.GET("/foo", func(c *gin.Context) {
c.HTML(http.StatusOK, "bar.tmpl", gin.H{
"title": "Foo website",
})
})
router.GET("favicon.ico", func(c *gin.Context) {
file, _ := f.ReadFile("assets/favicon.ico")
c.Data(
http.StatusOK,
"image/x-icon",
file,
)
})
router.Run(":8080")
}
|
Developers can simply wrap static files in two lines:
1
2
|
//go:embed assets/* templates/*
var f embed.FS
|
The route for static files can be set directly from the bottom:
1
2
|
// example: /public/assets/images/example.png
router.StaticFS("/public", http.FS(f))
|
You can also read a single file with ReadFile
:
1
2
3
4
5
6
7
8
|
router.GET("favicon.ico", func(c *gin.Context) {
file, _ := f.ReadFile("assets/favicon.ico")
c.Data(
http.StatusOK,
"image/x-icon",
file,
)
})
|
Program examples can be found directly at here.
Summary
The Go team is really dedicated and will include some common core features in the official maintenance to keep it up to date. With this feature, you can skip the static files and add them to Docker directly in the Go deployment process. In the future, some confidential files of the project can be replaced directly in the CI process and then go build.