Closed8
【Go】httpリクエストを投げるコードから学ぶ
教材
参考にさせていただくコードはこちら
宛先だけexample.com
に変更しています。
main.go
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://example.com", nil)
if err != nil {
log.Fatal(err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", b)
}
実行結果
バージョン
$ go version
go version go1.19.4 linux/amd64
結果
$ go run main.go
200 OK
<!doctype html>
<html>
<head>
<title>Example Domain</title>
... 略 ...
httpリクエスト生成
main.go
req, err := http.NewRequest("GET", "https://example.com", nil)
if err != nil {
log.Fatal(err)
}
変数宣言
- varの変数定義の短縮版
httpリクエスト生成
-
(*Request, error)
が返され、req
とerr
に格納
エラー処理
- エラーが起きたら(
err
に格納される)log.Fatal
でログ出力
httpリクエスト実行
main.go
client := &http.Client{}
...
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
http.client構造体初期化
httpリクエスト実行(client.Do)
- 引数に
request
が必要(http.newrequest
で生成したもの) -
(*Response, error)
を返し、resp
とerr
に格納 -
client.Get
はカスタムヘッダを使用できないが、こちらは使用可能
To make a request with custom headers, use NewRequest and Client.Do.
To make a request with a specified context.Context, use NewRequestWithContext and Client.Do.
response.Bodyをクローズする
main.go
defer resp.Body.Close()
なぜ?
ドキュメントにこうあります
The client must close the response body when finished with it:
https://pkg.go.dev/net/http#pkg-overview
これをしないと、TCPコネクションが残り続け、ファイルディスクリプタが枯渇するそうです
httpステータスコード出力
main.go
fmt.Println(resp.Status)
ステータスコード出力
- "200 OK"のように
string
で出てくるそうです
type Response struct {
Status string // e.g. "200 OK"
response.Body読み込み
main.go
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
なぜBodyを読み込むか
ドキュメントにこうある
default HTTP client's Transport may not reuse HTTP/1.x "keep-alive" TCP connections if the Body is not read to completion and closed.
keepaliveできず、コネクションの再利用ができないかららしい
ioutilはdeprecated
ioパッケージを使うのが推奨らしいです
つまり以下のように書き換えられます。
import (
"io"
)
func main() {
...
b, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
response.Body出力
main.go
fmt.Printf("%s", b)
%s
とは?
string
を表します。
%<記号>
とすることで値をフォーマットできます
フォーマットの一覧は以下を参照
つまり今回は何をしているの?
string
型で出力しています。
Readall
したものはbyte
型であるため、変換する必要があります。
このスクラップは2023/01/02にクローズされました