[GO語言] 構造帶有請求體的HTTP GET
前言
傳統的 web 應用約定 http.GET 請求不允許攜帶請求體。然而現在已是 9102 年,restful style的介面逐漸流行,通常我們在查詢某個資源的時候會使用 http.GET 作為請求方法,使用 json 格式的請求體作為查詢條件 (舉個例子,elasticsearch 的查詢介面就是 http.GET,並把查詢條件放在請求體裡面)
使用 net/http Client
Golang 有原生的 httpclient (java 11 終於也有原生的 httpclient 了),通過以下程式碼可以得到:
import"net/http" func main() { client := &http.Client{} }
我們來看看 http.Client 上都有些什麼常用方法:
從 Get 方法的簽名看出,http.Get 不能附帶請求體,看來 Golang 的 httpclient 也沒有摒棄老舊的思想呢。別急,接著往下看
深入到 Post 方法內部,有以下原始碼
func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error) { req, err := NewRequest("POST", url, body) if err != nil { return nil, err } req.Header.Set("Content-Type", contentType) return c.Do(req) }
不難看出,Post 方法內部是先使用 NewRequest()
構造出 http 請求,然後使用 client.Do(request)
來執行 http 請求,那麼我們是否能使用 NewRequest()
構造出帶有請求體的 http.GET 請求? 依照原始碼,我給出以下程式碼:
client := &http.Client{} //構造http請求,設定GET方法和請求體 request, _ := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/test", bytes.NewReader(requestBodyBytes)) //設定Content-Type request.Header.Set("Content-Type", "application/json") //傳送請求,獲取響應 response, err := client.Do(request) defer response.Body.Close() //取出響應體(位元組流),轉成字串列印到控制檯 responseBodyBytes, err := ioutil.ReadAll(response.Body) fmt.Println("response:", string(responseBodyBytes))
實踐結果也是正確的,使用 NewRequest()
確實可以構造附帶請求體的 http.GET 請求 (Golang 並沒有拒絕這樣的構造),只是 net/http 並沒有對外暴露相應的 Get 方法