GoRequest 是一個極簡的 HTTP 客戶端,作者靈感來源於 Node.js 庫 SuperAgent。相比 Golang 標准庫 net/http
,GoRequest 使用起來更加簡單。GoRequest 官方的口號是 “像機槍一樣發送請求”。
GoRequest 包含以下功能:
- 支持 HTTP 請求方式:Get/Post/Put/Head/Delete/Patch/Options
- 支持設置 header 請求頭
- 支持使用 JSON 字符串作為請求參數
- 支持將多路請求的方式發送數據和文件
- 支持通過代理發送請求
- 支持為請求設置超時
- 支持 TLS 客戶端設置
- 支持設置重定向策略
- 支持為請求設置 cookie
- CookieJar - automatic in-memory cookiejar
- 支持請求頭設置基本身份認證
安裝方式:
go get github.com/parnurzeal/gorequest
02
HTTP 請求方式
Golang 發送一個簡單的 Get 請求,使用 net/http
標准庫和使用 GoRequst 庫,兩種發送 Get 請求的方式都比較簡單。
示例代碼如下:
標准庫方式:
resp, err := http.Get("http://example.com/")
GoRequest 庫方式:
request := gorequest.New()
resp, body, errs := request.Get("http://example.com/").End()
或(該 GoRequest 方式無法復用對象)
resp, body, errs := gorequest.New().Get("http://example.com/").End()
閱讀上面這兩段代碼,我們可以發現,使用標准庫的方式發送 Get 請求,甚至比使用 GoRequest 庫的方式發送 Get 請求更加簡單。
但是,當我們需求稍作修改,比如我們需要為 Get 請求,設置 header 頭和設置重定向策略。我們再來看一下分別使用標准庫和 GoRequest 庫兩種實現方式。
標准庫方式:
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
req, err := http.NewRequest("GET", "http://example.com", nil)
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
GoRequest 庫方式(其它 HTTP 請求方式與 Get 使用方式相同):
request := gorequest.New()
resp, body, errs := request.Get("http://example.com").
RedirectPolicy(redirectPolicyFunc).
Set("If-None-Match", `W/"wyzzy"`).
End()
閱讀上面兩段代碼,很容易發現使用 GoRequest 方式使實現更加簡單。使用標准庫方式,首先需要創建一個 Client,然后使用不同的命令設置 header 頭等操作,這僅僅是為了實現一個 HTTP 請求。而使用 GoRequest 方式,僅需鏈式調用兩個方法即可輕松實現。
03
JSON 格式請求參數
在 Golang 語言中,如果使用標准庫 net/http
發送請求參數為 JSON 格式的 POST 請求,首先需要先將 map 或 struct 類型的數據,使用標准庫 encoding/json
的 Marshal 方法,將數據轉換為 JSON 格式的數據,並且設置 header 頭參數 Content-Type
的值為 application/json
,然后創建一個 Client,最終你的代碼變得越來越長,越來越難維護。
標准庫方式:
m := map[string]interface{}{
"name": "backy",
"species": "dog",
}
mJson, _ := json.Marshal(m)
contentReader := bytes.NewReader(mJson)
req, _ := http.NewRequest("POST", "http://example.com", contentReader)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Notes","GoRequest is coming!")
client := &http.Client{}
resp, _ := client.Do(req)
如果使用 GoRequest 庫發送請求參數為 JSON 格式的 POST 請求,因為它默認支持 JSON 格式的請求參數,所以它只需要一行代碼就可以實現。
GoRequest 庫方式:
request := gorequest.New()
resp, body, errs := request.Post("http://example.com").
Set("Notes","gorequst is coming!").
Send(`{"name":"backy", "species":"dog"}`).
End()
04
支持回調函數 Callback
GoRequest 庫還支持回調函數,你可以根據自己的項目需求靈活使用它,回調函數示例代碼如下:
func printStatus(resp gorequest.Response, body string, errs []error){
fmt.Println(resp.Status)
}
gorequest.New().Get("http://example.com").End(printStatus)
05
請求控制
在 Golang 項目開發中,有時我們可能需要對請求做一些額外控制,比如超時處理,重試請求 N 次,重定向處理等。GoRequest 庫都可以為我們提供簡單的實現方式。
超時處理:
request := gorequest.New().Timeout(2*time.Millisecond)
resp, body, errs:= request.Get("http://example.com").End()
需要注意的是,Timeout 是將 Dial 連接和 IO 讀寫的耗時總和,與時間參數作比較。
重試請求:
request := gorequest.New()
resp, body, errs := request.Get("http://example.com/").
Retry(3, 5 * time.Second, http.StatusBadRequest, http.StatusInternalServerError).
End()
閱讀上面這段代碼,它的含義是當服務器返回結果是 http.StatusBadRequest
或 http.StatusInternalServerError
時,會每隔 5 秒重試請求一次,共重試 3 次。
重定向處理:
request := gorequest.New()
resp, body, errs := request.Get("http://example.com/").
RedirectPolicy(func(req Request, via []*Request) error {
if req.URL.Scheme != "https" {
return http.ErrUseLastResponse
}
}).
End()
閱讀上面這段代碼,它的含義是將 http 請求重定向為 https 請求。
06
返回結果處理方式
讀者朋友們可能已經發現,以上示例代碼都是以 End 結束,End 的含義是返回結果是字符串類型,如果我們希望返回結果是其他類型,比如字節類型和結構體類型,可以將 End 分別替換為 EndBytes 和 EndStruct。
EndBytes 格式:
resp, bodyBytes, errs := gorequest.New().Get("http://example.com/").EndBytes()
EndStruct 格式:
heyYou struct {
Hey string `json:"hey"`
}
var heyYou heyYou
resp, _, errs := gorequest.New().Get("http://example.com/").EndStruct(&heyYou)
07
總結
本文我們介紹 Golang 語言的極簡 HTTP 客戶端 GoRequest 以及它的使用方法。它比標准庫 net/http
使用方式簡單,當我們項目開發中需要使用 HTTP 方式調用接口時,強烈推薦使用 GoRequest 庫。
GoRequest 底層在大多數用例中是基於 http.Client
實現的,所以通過一次調用 gorequest.New()
得到的對象,應盡可能多次使用。
GoRequest 除了上面介紹的 JSON 參數,它還支持 Struct 和 File,感興趣的讀者可以查閱官方文檔了解相關內容。
推薦閱讀:
Golang 語言 gRPC 使用的接口設計語言 protobuf
Golang 語言怎么使用 go-micro 和 gin 開發微服務?
參考資料:
https://github.com/parnurzeal/gorequest