http【Go】
httpに関する処理を紹介します。
まずは簡単に取得をする例です。
resp, err := http.Get("http://example.com") if err != nil { log.Fatalln(err) } defer resp.Body.Close() // 必ずClose()する。怠ると、デフォルトで有効のkeep-alive要求によってTCPコネクションが再利用されないため body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatalln(err) } fmt.Println(string(body)) // byte配列をstringにcast
レスポンスの取得に成功したら、bodyは必ずCloseするようにします。
Closeしないと、TCPコネクションが再利用されません。
条件付きリクエストなど、ヘッダー情報をカスタマイズしたい場合には、
次のようにします。
base, _ := url.Parse("https://example.com/") reference, _ := url.Parse("/test?a=1&b=2") endpoint := base.ResolveReference(reference).String() fmt.Println(endpoint) // req, _ := http.NewRequest("GET", endpoint, nil) // GETの例 req, _ := http.NewRequest("POST", endpoint, bytes.NewBuffer([]byte("password"))) // passwordをHTTPリクエストボディにつけてPOST req.Header.Add("If-None-Match", `W/"wyxxy"`) // headerを追加し、条件付きリクエストにする。テストのため、内容は正確ではない q := req.URL.Query() q.Add("c", "3&%") // クエリ要素を追加 fmt.Println(q) // map形式でクエリ要素を出力 fmt.Println(q.Encode()) req.URL.RawQuery = q.Encode() // エンコードすることで、クエリ要素に&などを用いても問題ない var client = &http.Client{Timeout: time.Second * 10} // Timeoutはdefault設定にないため、設定推奨 resp, err := client.Do(req) // req.URL.RawQueryに指定した内容が不正であるため、404 NotFoundが返される if err != nil { log.Fatalln(err) } defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(body))
struct http.Clientの中身にTimeoutを設定することが推奨されます。
何らかの理由で参照先のAPIサーバーが停止状態に陥った時、
Goのhttp.Clientはデフォルトでタイムアウトに関する設定はされていないため、
プログラムも、その応答が無いことに合わせて、停止してしまいます。
より詳細な設定も可能です。参考資料の2番目を参照ください。