[英]REST application folder structure in golang
我剛剛開始使用Go,作為第一個項目,我決定創建一個簡單的REST API服務器。 不幸的是,我遇到了一個問題,因為我似乎無法找到構建項目的最佳方法。
到目前為止,我使用與Rails項目相同的結構,這意味着在自己的文件夾中有控制器和模型,但它不像go代碼那樣慣用。
有沒有人對如何正確構建項目有任何建議?
它可能是可行的,但是由於靜態編譯,如果你想要很多Rails用於計算路由的自動化,你將會有點混亂。
我可能只有一個包含所有數據庫模型的models
包,然后基於Gorilla的多路復用器將某些路由綁定到某些操作。
如果事情變得復雜,你可以嘗試更大的框架,比如Revel ,它可能更適合更大的MVC應用程序。
將項目保存在一個文件夾中。 Go將子文件夾視為單獨的包。 以下是CMS應用程序的示例: https : //github.com/calebdoxsey/tutorials/tree/master/appengine/cms 。
我創建了一個在init
函數中定義路由的文件:(使用httprouter )
router.GET("/api/documents/:id", serveDocumentsGet)
基本上每個端點都有自己的功能:
func serveDocumentsGet(res http.ResponseWriter, req *http.Request, params httprouter.Params) {
serveAPI(res, req, func() interface{} {
ctx := appengine.NewContext(req)
session, _ := sessionStore.Get(req, "session")
email, ok := session.Values["email"].(string)
if !ok {
return HTTPError{403, "access denied"}
}
userKey := datastore.NewKey(ctx, "User", email, 0, nil)
docKey := datastore.NewKey(ctx, "Document", params.ByName("id"), 0, userKey)
var document Document
err := datastore.Get(ctx, docKey, &document)
if err != nil {
return err
}
return document
})
}
serveAPI
只是一個處理json編碼和錯誤的便利函數:
func serveAPI(res http.ResponseWriter, req *http.Request, handler func() interface{}) {
res.Header().Set("Content-Type", "application/json")
result := handler()
if err, ok := result.(HTTPError); ok {
res.WriteHeader(err.Code)
json.NewEncoder(res).Encode(map[string]string{
"error": err.Message,
})
} else if err, ok := result.(error); ok {
res.WriteHeader(500)
json.NewEncoder(res).Encode(map[string]string{
"error": err.Error(),
})
} else if rc, ok := result.(io.ReadCloser); ok {
io.Copy(res, rc)
rc.Close()
} else {
json.NewEncoder(res).Encode(result)
}
}
基本上我試圖避免魔術,所以所有的端點都很明確。
這為您提供了控制器和模型(對於更復雜的模型,我將它們分解為單獨的文件...請參閱用戶示例)。
對於視圖,您可以使用內置的go模板包。 創建一個文件夾(可能是static/tpl/yourtemplate.gohtml
)並使用template.ParseFiles
和tpl.Execute
來渲染它們。 (再一次這是明確的......沒有魔法)
但越來越多的我發現我的大部分觀點都是通過javascript在客戶端完成的。 如果你這樣做,那么你所要做的就是提供文件:
static := http.FileServer(http.Dir("static"))
router.GET("/static/*filepath", func(res http.ResponseWriter, req *http.Request, params httprouter.Params) {
filepath := params.ByName("filepath")
req.URL.Path = filepath
static.ServeHTTP(res, req)
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.