Go Web開發入坑指南

原創做者,公衆號【程序員讀書】,歡迎關注公衆號,轉載文章請註明出處哦。nginx

在Go語言中開發Web應用,真的是一件很是簡單的事情,由於Go語言標準庫中就有很是成熟且簡單的Web開發包:net/http程序員

net/http封裝了開發Web應用所須要的大部分功能,所以,在Go語言中使用net/http開發Web應用程序時,咱們甚至都不用像其餘語言(好比PHP)同樣須要本身再搭一個Apache或nginx等Web服務器,而是隻須要簡單幾行代碼就能夠搭建一個Web服務應用。web

Web基礎

固然,雖然使用Go的net/http包能夠簡單開發Web應用,但咱們在開發中仍然須要牢固地掌握開發Web程序所須要的基礎知識,而Web開發中最基礎和最核心的知識就是:HTTP協議編程

http協議是Web服務器與客戶端(最多見就是瀏覽器)之間通信的語言與規範,瀏覽器向Web發起請求到Web服務器響應並結束鏈接,整個過程以下圖所示:瀏覽器

圖片摘自《HTTP權威指南》

請求與響應

一個完整http事務,由一個客戶端的請求和Web服務器響應構成,客戶端發起的請求,包括三個部分:請求行請求頭請求體,而Web服務器的響應一樣包含三部分:響應行響應頭響應體,以下圖所示:。bash

圖片摘自《HTTP權威指南》

http協議的相關知識遠不僅這些,咱們有空再談談。服務器

Go建立Web服務器的幾種方式

http.HandleFunc函數

使用HandleFunc函數是http封裝好的一個函數,能夠直接使用,第一個參數是web請求路徑,第二個參數是的func(writer http.ResponseWriter, request *http.Request)函數。函數

再使用http.ListenAndServe(":8080",nil)語句,監聽8080端口,運行程序後。學習

使用http://localhost:8080,便會輸出一塊兒學習Go Web編程吧ui

其中http.ResponseWriter表明對客戶端的響應體,而http.Request表明客戶端發送服務器的請求數據。

func hello(writer http.ResponseWriter, request *http.Request) {
    writer.Write([]byte("一塊兒學習Go Web編程吧"));
}

func main(){
    http.HandleFunc("/hello",hello)
    log.Fatal(http.ListenAndServe(":8080",nil))
}

複製代碼

http.Handle函數

HandleFunc同樣,Handle也是http封裝好的函數,第一個參數跟HandleFunc同樣,而第二個參數則是必須是實現了http.Handler接口的類型,http.Handler在http包的定義以下:

type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}
複製代碼

下面咱們定義一個Controller結構體,在該結構定義ServeHTTP方法,所以Controller結構也實現http.Handler接口,而經過http.HandlerFunc也能將hello方法轉成一個實現http.HandlerFunchttp.HandlerFunc也實現http.Handlerhttp.HandlerFunc在http包的定義以下:

type HandlerFunc func(ResponseWriter, *Request)

// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
	f(w, r)
}
複製代碼

其實,在上面的例子中,咱們將hello傳給http.HandleFunc函數時,HandleFunc函數也是使用http.HandlerFunc將hello轉換成http.HandlerFunc的。

下面有關http.Handle的示例:

type Controller struct {}
func (c Controller)ServeHTTP(writer http.ResponseWriter, request *http.Request){
    writer.Write([]byte("hello,1"));
}

func hello(writer http.ResponseWriter, request *http.Request) {
    writer.Write([]byte("hello,2"));
}

func main(){
    http.Handle("/hello1",&Controller{})
    http.Handle("/hello2",http.HandlerFunc(hello))
    log.Fatal(http.ListenAndServe(":8080",nil))
}
複製代碼

運行程序後,在瀏覽器輸入下面的地址:

http://localhost:8080/hell1, 輸出:hello,1

http://localhost:8080/hell2, 輸出:hello,2

http.ServeMux

不管是使用http.Handle仍是http.HandleFunc函數,其實底層代碼都是使用http.DefaultServeMuxDefaultServeMux的定義以下代碼所示:

var DefaultServeMux = &defaultServeMux

var defaultServeMux ServeMux
複製代碼
type Controller struct {}
func (c Controller)ServeHTTP(writer http.ResponseWriter, request *http.Request){
    writer.Write([]byte("hello,1"));
}

func hello(writer http.ResponseWriter, request *http.Request) {
    writer.Write([]byte("hello,2"));
}

func main(){
    mux := &http.ServeMux{}
    mux.HandleFunc("/hello1",hello)
    mux.Handle("/hello2",http.HandlerFunc(hello))
    mux.Handle("/hello3",&Controller{})

    log.Fatal(http.ListenAndServe(":8080",mux))
}
複製代碼

運行程序後,在瀏覽器輸入下面的地址:

http://localhost:8080/hell1, 輸出:hello,1

http://localhost:8080/hell2, 輸出:hello,1

http://localhost:8080/hell3, 輸出:hello,2

http.Server

http.Server是http包中對web更加底層的支持,咱們前面使用的方法,都是對http.Server的封裝而已,若是直接使用http.Server,則能夠自定義更多的參數,若是鏈接超時等參數,所以咱們下面直接使用http.Server開發Web服務。

func main() {
    myHandler := &http.ServeMux{}
    myHandler.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("hello"))
    })
    s := &http.Server{
        Addr:           ":8080",
        Handler:        myHandler,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }
    log.Fatal(s.ListenAndServe())
}

複製代碼

運行程序後,在瀏覽器輸入下面的地址:

http://localhost:8080/hello, 輸出:hello

總結

經過上面的例子,能夠看出Go Web開發可很簡單,可是實際中,一個真正Web應用所要作的事,遠不僅這麼簡單,對於Go Web開發,仍是有不少東西要學的。


你的關注,是我寫做路上最大的鼓勵!

相關文章
相關標籤/搜索