Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

go 1.16 embed - strip directory name

Tags:

go

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?

like image 524
George Livanoss Avatar asked Oct 20 '25 15:10

George Livanoss


1 Answers

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
like image 102
Peter Avatar answered Oct 23 '25 07:10

Peter