2015-06-02 50 views
-1

this Blake Mizerany的Golang講話的Youtube視頻(在15:29左右),他談到了如何在不使用第三方包的情況下構建路由器,如何構建一個具有可變組件的路由,比如一個id。這是他使用,以顯示如何獲取路線的可變部分的第一行處理程序(即鑰匙)在沒有第三方路由庫的情況下路由PUT請求

func productHandler(w http.ResponseWriter, r *http.Request){ 
    key := r.URL.Path[len("/products/":] 
    switch r.Method{ 
    case "GET": 
     //do stuff 
    case "POST" 
     //do stuff 
    default: 
     http.Error(w, "method not allowed", 405) 
    } 
} 

這不是從他的介紹,雖然他有什麼實際的路線看起來清晰。

我正在嘗試構建一個處理帶有id的放置請求的路由。當我點擊我的頁面上的元素,它發送一個PUT請求到這條路線

http://localhost:8080/products/1433255183951 

我有這樣

http.HandleFunc("/products/{id}", doSomethingWithProduct){ 

    } 

當然路線有FUNC

func doSomethingWithProduct(res http.ResponseWriter, req *http.Request{ 
    key := req.URL.Path[len("/products/"):] 

    log.Println(key, "is this logging?? nope") 

} 

問題。即使我已經設置了路由和處理程序,當我點擊元素時我找不到404,但沒有跡象表明我的函數被調用(即它不記錄)

問題:如何創建一個處理一個PUT請求

http://localhost:8080/products/1433255183951 

回答

3

http.HandleFunc不處理「捕獲組」就像你試圖用{id}做。

http.HandleFunc("/products/", handler)將匹配以這種模式開頭的所有路線。你必須自己解析其餘部分。

請參閱ServeMux

ServeMux是HTTP請求多路複用器。它將每個傳入請求的URL與註冊模式列表進行匹配,並調用與URL最匹配的模式的處理程序。

模式名固定,帶根路徑,像「/favicon.ico」,或根的子樹,如「/圖像/」(注意斜線)。較長的模式優先於較短的模式,因此如果有處理程序註冊了「/ images /」和「/ images/thumbnails /」,後一個處理程序將調用路徑以「/ images/thumbnails /」開頭,前者將接收「/ images /」子樹中任何其他路徑的請求。

注意的是,由於圖案斜線名稱結尾的植根子樹,模式「/」不被其他註冊模式匹配,而不是僅僅與路徑==「/」的URL的所有路徑相匹配。

模式可以有選擇地以主機名開頭,限制與該主機上的URL匹配。特定於主機的模式優先於一般模式,因此處理程序可能會註冊兩種模式「/ codesearch」和「codesearch.google.com/」,但不會接管「http://www.google.com/」的請求。

ServeMux還負責清理URL請求路徑,重定向任何包含的請求。或..元素添加到等效的.-和..-免費網址。

+0

,你和JimB都回應了「5分鐘前」。我不知道誰會接受,所以我會拋硬幣。不過,我投了你們兩個。 – BrainLikeADullPencil

3

HandleFunc一個自定義路由/ FUNC不知道如何處理{id}做什麼。給它可以匹配特定的路徑:

http.HandleFunc("/products/", doSomethingWithProduct) 
+0

你都回答 「5分鐘前」。我不知道誰會接受,所以我會拋硬幣。不過,我投了你們兩個。根據SO, – BrainLikeADullPencil

3

內置的HTTP路由器並不像綁定參數那樣花哨;但是,您可以指定與處理程序關聯的整個前綴。請參閱http.ServeMux的文檔。

嘗試這樣:

func main() { 
    productsPrefix := "/products/" 
    http.HandleFunc(productsPrefix, func(w http.ResponseWriter, r *http.Request) { 
    if (r.Method == "PUT") && (strings.Index(r.URL.Path, productsPrefix) == 0) { 
     productId := r.URL.Path[len(productsPrefix):] 
     fmt.Printf("OK: %s %s productId=%s\n", r.Method, r.URL.Path, productId) 
    } 
    }) 

    log.Print("Listening on localhost:8080") 
    log.Fatal(http.ListenAndServe(":8080", nil)) 
} 

例如:

$ curl -XPUT http://localhost:8080/products/1234 
# => OK: PUT /products/1234 productId=1234 
相關問題