2

私は、Webアプリケーションをプログラミングするときにどこにでもhttp.ResponseWriterを渡す必要がないかどうかを理解しようとしています。私は単純なmvcWebフレームワークをセットアップしていますが、最後の関数などでのみ使用されている場合は、http.ResponseWriterをさまざまな関数に渡す必要があります。

ルートパッケージ

// Struct containing http requests and variables
type UrlInfo struct {
    Res http.ResponseWriter
    Req *http.Request
    Vars map[string]string
}

func HandleFunc(handlepath string, runfunc func(*UrlInfo)) {
    // Set handler and setup struct
    http.HandleFunc(getHandlePath(handlepath), func(w http.ResponseWriter, r *http.Request) {
        url := new(UrlInfo)
        url.Res = w
        url.Req = r
        url.Vars = parsePathVars(r.URL.Path, handlepath)

        runfunc(url)
    })
}

// Parse file and send to responsewriter
func View(w http.ResponseWriter, path string, data interface{}) {
    // Go grab file from views folder
    temp, err := template.ParseFiles(path+".html")
    if err != nil {
        // Couldnt find html file send error
        http.Error(w, err.Error(), http.StatusInternalServerError)
    } else {
        temp.ExecuteTemplate(w, temp.Name(), data)
    }
}

コントローラパッケージ

import (
    "routes"
)

func init() {
    // Build handlefunc
    routes.HandleFunc("/home/", home)
}

func home(urlinfo *routes.UrlInfo) {
    info := make(map[string]string)
    info["Title"] = urlinfo.Vars["title"]
    info["Body"] = "Body Info"

    gi.View(urlinfo.Res, "pages/about", info)
}

home関数に何も渡さなくてもよいので、ビュー関数に再度渡して吐き出すことができます。一箇所にセットして、必要なときにいつでも引き出せるといいですね。これは、同じ点でルートパッケージと通信する複数のパッケージに関しても便利です。

ありとあらゆる考え、ヒント、またはトリックを歓迎します。ありがとう。

4

1 に答える 1

5

これを行うにはいくつかの方法があります。秘訣は、通過するResponseWriterから実際に何が必要かを把握することです。ちょっとした関数合成をするだけでいいようです。

ビューがio.Readerと、ResponseWriterにパイプできるエラーを返すようにデザインを変更します。完全にテストされていない例を次に示します。

func View(path string, data interface{}) (io.Reader, error) {
    // Go grab file from views folder
    temp, err := template.ParseFiles(path+".html")
    if err != nil {
        // Couldnt find html file send error
       return nil, err
    } else {
        buf := bytes.Buffer()
        temp.ExecuteTemplate(buf, temp.Name(), data)
        return buf
    }
}

func HandleFunc(handlepath string, runfunc func(*UrlInfo) (io.Reader, error)) {
    // Set handler and setup struct
    http.HandleFunc(getHandlePath(handlepath),
                    func(w http.ResponseWriter, r *http.Request) {
        url := new(UrlInfo)
        url.Res = w
        url.Req = r
        url.Vars = parsePathVars(r.URL.Path, handlepath)

        rdr, err := runfunc(url)
        io.Copy(w, rdr);
    })
}

これにより、http ResponseWriterについて心配する必要があるのは、HandleFunc関数だけです。

于 2012-09-21T04:26:24.623 に答える