Go - Embed
Go 1.16 added a new embed package.
While the idea is not a novelty, there were already some packages with slightly different APIs fulfilling similar roles, for example:
Having an official package is always a welcome addition to the batteries-included standard library.
Usage
A possible way to embed react assets could be as simple as:
package web
import (
"embed"
"io/fs"
)
//go:embed build/*
var content embed.FS
And serving assets using http.FileServer
:
http.Handle("/static/", http.FileServer(http.FS(content)))
However, following this structure, one may end up with some unexpected 404 responses.
Exploring Embed
Fortunately, go list
gained some new fields we can use to understand how embed works.
.EmbedPatterns
displays patterns being used:
$ go list -f '{{ join .EmbedPatterns "\n" }}' ./...
build/*
It can even detect if a pattern is not matching any resources:
$ go list -f '{{ join .EmbedPatterns "\n" }}' ./...
client/client.go:10:20: pattern foobar/*: no matching files found
Another addition to go list
is allowing to list embed files:
go list -f '{{ join .EmbedFiles "\n" }}' ./...
build/favicon.ico
build/index.html
build/logo512.png
build/robots.txt
build/static/css/main.6dea0f05.chunk.css
build/static/js/2.6071c2c3.chunk.js
In this case, we can observe using the directive //go:embed build/*
will include the build
directory and all files in the directory.
If the files being served are not expecting to be in build
directory it is possible to change the subtree:
// Contents helper function
func Contents() (fs.FS, error) {
return fs.Sub(content, "build")
}
Embed package seems an exciting addition to the Go standard library.
I am curious to see which uses cases are possible. For now, I am expecting it to become the de facto solution to store database migration scripts and assets in low traffic apps.
Example code is available in https://github.com/jacoelho/sample-go-react