web
服務毫無疑問是現代資訊高速公路的實現者,我們平時的衝浪上網,購買商品,線上學習都是依賴web服務。golang
號稱實現了一套完善的網路服務,查閱資料時,大家都在說使用golang
很容易搭建web
服務。其實本人很討厭在編碼過程中說容易簡單的詞語,因為一切在編碼之前的斷言都是空談,因為你不可能想到所有編碼細節,就無法準確判斷出一個服務的實現是否真的簡單。即使golang
確實可以使用較少的程式碼實現一個簡單的web
服務,但是程式碼的背後並不簡單,你要學習的不是那幾行簡單的程式碼,而程式碼之後的原理才具有真正的價值。
package main
import (
"fmt"
"net/http"
"log"
)
// '/'模式對應的處理函式
func rootHandler(response http.ResponseWriter, request *http.Request) {
fmt.Fprintf(response, "Pattern is '/', URL is " + request.URL.Path)
}
// '/getResource/'模式對應的處理函式
func resourceHandler(response http.ResponseWriter, request *http.Request) {
fmt.Fprintf(response, "Pattern is '/getResource/', URL is " + request.URL.Path)
}
func main() {
// 將pattern註冊到對應的處理函式
http.HandleFunc("/", rootHandler)
http.HandleFunc("/getResource/", resourceHandler)
// 監聽80埠,開啟web服務
err := http.ListenAndServe(":80", nil)
if err != nil {
log.Fatal("ListenAndServe:", err)
}
}
複製程式碼
一個簡單的web
服務只需要一個檔案就實現了,該檔案中定義了main
包,然後定義了兩個處理模式的函式,最後是main
主函式。什麼是處理模式的函式?其實就是告訴web
服務,如何從url
找到其對應的處理函式。如果讀者使用過正規表示式,大概能理解到字串‘/getResource/haha
’可以匹配模式'/getResource/
'。同理,‘www.baidu.com/getResource/haha
’可以匹配到模式‘/getResource/
’,那麼該模式對應的處理函式是什麼呢?我們是通過以下方式告訴web
服務的:
// 將pattern註冊到對應的處理函式
http.HandleFunc("/", rootHandler)
http.HandleFunc("/getResource/", resourceHandler)複製程式碼
最後web
服務就可以從‘www.baidu.com/getResource/haha
’找到resourceHandler
函式來處理了。
我們看下main
函式中的程式碼邏輯在表達什麼,首先,將pattern
註冊到對應的處理函式,其次監聽80
埠,開啟web
服務,最後,失敗了怎麼辦?失敗處理也是編碼中非常重要的一環。如果我能保證每一步程式碼執行都是預期成功的,那程式碼還不寫的飛起,事實上引數檢查,錯誤處理,日誌輸出都是軟體開發中非常重要的環節。我們在編碼過程中既在寫符合預期的邏輯其實也在寫不符合預期時程式碼該怎麼處理。你以為程式碼bug
是什麼?程式碼bug
就是異常處理的還不夠,想的還不夠完善,這是填不完的坑。
讀者應該站在軟體開發者的角度來閱讀原始碼,和人之間有了跨越時空的交流,才有真正意義上的學習。如果我是讀者,如何閱讀main
函式這段程式碼邏輯呢?我們需要站在軟體開發者的角度有層次感的閱讀原始碼。在應用程式這一層,我首先通過HandleFunc
註冊了兩個pattern
對應的處理函式,這樣應用程式就知道如何通過url
找到處理函式了。其次,讓應用程式監聽80
埠,然後提供web服務。最後如果失敗了,列印日誌就退出,其實就是讓應用程式告訴程式設計師,哎呀,監聽以及開啟web
服務失敗了,程式設計師你快看看吧。到此為止,軟體開發者想要表達的應用程式層面的邏輯已經完成了。作為一個搬磚的程式設計師學到這一步就可以了,至少以後複製貼上快多了。但是這僅僅是軟體開發者在應用程式層面的邏輯讀者已經掌握了,但是http
包層面的邏輯,以及更深入net
包層面的邏輯你瞭解了嗎?以後web服務更復雜的需求難道就憑藉學到這簡單的邏輯就能搞定了嗎?當然不可能。如果我是讀者,這時候我會發問:
HandleFunc
函式在http
層面做了什麼?怎麼就能將pattern
和處理函式對應起來了呢?ListenAndServe
函式做了啥?是怎麼監聽80
埠的?web
服務怎麼開啟的?
帶著上面的疑問看下一篇文章吧,這一篇文章廢話空話太多了,佔用了篇幅。