2013-03-06 92 views
49

我試圖找出在Go中處理對//的請求並以不同方式處理不同方法的最佳方法。這裏是我所想到的最好的:如何處理Go中不同方法的http請求?

package main 

import (
    "fmt" 
    "html" 
    "log" 
    "net/http" 
) 

func main() { 
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 
     if r.URL.Path != "/" { 
      http.NotFound(w, r) 
      return 
     } 

     if r.Method == "GET" { 
      fmt.Fprintf(w, "GET, %q", html.EscapeString(r.URL.Path)) 
     } else if r.Method == "POST" { 
      fmt.Fprintf(w, "POST, %q", html.EscapeString(r.URL.Path)) 
     } else { 
      http.Error(w, "Invalid request method.", 405) 
     } 
    }) 

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

這是否是慣用的Go?這是最好的,我可以用標準的http lib做什麼?我寧願做一些像http.HandleGet("/", handler)這樣的快遞或Sinatra。編寫簡單的REST服務有沒有一個好的框架? web.go看起來很有吸引力,但似乎停滯不前。

謝謝您的建議。

+2

如果您只是在尋找路由抽象,您可能會對http://www.gorillatoolkit.org/pkg/mux感興趣。 – dskinner 2013-03-06 07:36:32

+1

+1。 mux或http://www.gorillatoolkit.org/pkg/pat非常適合抽象。 – minikomi 2013-03-06 08:12:36

回答

45

爲確保您只爲根服務:您正在做正確的事情。在某些情況下,您會想調用http.FileServer對象的ServeHttp方法,而不是調用NotFound;它取決於你是否有你想要服務的雜項文件。

以不同方式處理不同的方法:我的很多HTTP處理程序僅僅包含一個switch語句是這樣的:

switch r.Method { 
case "GET": 
    // Serve the resource. 
case "POST": 
    // Create a new record. 
case "PUT": 
    // Update an existing record. 
case "DELETE": 
    // Remove the record. 
default: 
    // Give an error message. 
} 

當然,你可能會發現一個第三方包像大猩猩爲你工作好。

20

呃,我實際上正在睡覺,因此看看http://www.gorillatoolkit.org/pkg/mux這個很好的評論,這是非常好的,做你想做的,只是讓文檔看看。例如

func main() { 
    r := mux.NewRouter() 
    r.HandleFunc("/", HomeHandler) 
    r.HandleFunc("/products", ProductsHandler) 
    r.HandleFunc("/articles", ArticlesHandler) 
    http.Handle("/", r) 
} 

r.HandleFunc("/products", ProductsHandler). 
    Host("www.domain.com"). 
    Methods("GET"). 
    Schemes("http") 

和許多其他的可能性,以及如何執行上述操作。

但我覺得有必要解決問題的另一部分,「這是我能做的最好的事情」。如果std lib太裸露,一個很好的資源在這裏:https://github.com/golang/go/wiki/Projects#web-libraries(特別鏈接到web庫)。