golang return static html file at specified route
Asked Answered
S

2

6

I am working on a simple todo app in go.

I have determined that all the pages except a user's list of todos can safely be a static html page. * Login form * new account form * index page that talks about the todo app

I see no reason currently for these to be go templates.

My question is how (within go, not using something like nginx) can I have a static html set to return at a specific route most efficiently?

For example index.html to be returned at "/"

I know I could do something like:

func GetNewAccount(res http.ResponseWriter, req *http.Request) {
        body, _ := ioutil.ReadFile("templates/register.html")
        fmt.Fprint(res, string(body))
}

or

var register, _ = string(ioutil.ReadFile("templates/register.html"))
func GetNewAccount(res http.ResponseWriter, req *http.Request) {
        fmt.Fprint(res, register)
}

To me these seems like more roundabout ways to do something seemingly simple.

Stilu answered 29/6, 2014 at 21:25 Comment(0)
D
10

If all your static files under the same tree, you could use http.FileServer:

http.Handle("/s/", http.StripPrefix("/s/", http.FileServer(http.Dir("/path/to/static/files/"))))

Otherwise pre-loading the html files you want into a map in func init() then making one handler to fmt.Fprint them based on the request's path should work.

Example of a simple static file handler :

func StaticFilesHandler(path, prefix, suffix string) func(w http.ResponseWriter, req *http.Request) {
    files, err := filepath.Glob(filepath.Join(path, "*", suffix))
    if err != nil {
        panic(err)
    }
    m := make(map[string][]byte, len(files))
    for _, fn := range files {
        if data, err := ioutil.ReadFile(fn); err == nil {
            fn = strings.TrimPrefix(fn, path)
            fn = strings.TrimSuffix(fn, suffix)
            m[fn] = data
        } else {
            panic(err)
        }
    }
    return func(w http.ResponseWriter, req *http.Request) {
        path := strings.TrimPrefix(req.URL.Path, prefix)
        if data := m[path]; data != nil {
            fmt.Fprint(w, data)
        } else {
            http.NotFound(w, req)
        }
    }
}

then you can use it like :

http.Handle("/s/", StaticFilesHandler("/path/to/static/files", "/s/", ".html"))
Doubletongued answered 29/6, 2014 at 21:32 Comment(2)
That surprises me. It may seem silly but all I am trying to do is be able to server template without the file extension. Obviously in production something like apache or ngnix could do this but I want to keep all that logic in the app.Stilu
It's rather easy to implement your own, I added an example.Doubletongued
F
-1

Or just use third party library and do something like this:

iris.StaticServe("/path/to/static/files","/theroute") //gzip compression enabled

The above code snippet is part of the Iris

Fluorspar answered 23/5, 2016 at 13:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.