George Livanoss
George Livanoss

Reputation: 599

go 1.16 embed - strip directory name

i was previously using statik to embed files into a Go application.

with Go 1.16 i can remove that deps

for example:

//go:embed static
var static embed.FS

fs := http.FileServer(http.FS(static))
http.Handle("/", fs)

this will serve the ./static/ directory from http://.../static/

Is there a way I can serve that directory from / root path, without /static?

Upvotes: 4

Views: 2395

Answers (1)

Peter
Peter

Reputation: 31751

Use fs.Sub:

Sub returns an FS corresponding to the subtree rooted at fsys's dir.

package main

import (
        "embed"
        "io/fs"
        "log"
        "net/http"
)

//go:embed static
var static embed.FS

func main() {
        subFS, _ := fs.Sub(static, "static")

        http.Handle("/", http.FileServer(http.FS(subFS)))

        log.Fatal(http.ListenAndServe(":4000", nil))
}

fs.Sub is also useful in combination with http.StripPrefix to "rename" a directory. For instance, to "rename" the directory static to public, such that a request for /public/index.html serves static/index.html:

//go:embed static
var static embed.FS

subFS, _ := fs.Sub(static, "static")
http.Handle("/", http.StripPrefix("/public", http.FileServer(http.FS(subFS))))

Alternatively, create a .go file in the static directory and move the embed directive there (//go:embed *). That matches a little more closely what the statik tool does (it creates a whole new package), but is usually unnecessary thanks to fs.Sub.

// main.go
package main

import (
    "my.module/static"
    "log"
    "net/http"
)

func main() {
    http.Handle("/", http.FileServer(http.FS(static.FS)))

    log.Fatal(http.ListenAndServe(":4000", nil))
}

// static/static.go
package static

import "embed"

//go:embed *
var FS embed.FS

Upvotes: 15

Related Questions