技術向上

プログラミングの学び、気になるテクノロジーやビジネストレンドを発信

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番目を参照ください。

http - The Go Programming Language

medium.com

developer.mozilla.org

developer.mozilla.org

satoyan419.com

blog.redbox.ne.jp