Closed8

【Go】httpリクエストを投げるコードから学ぶ

not75743not75743

教材

参考にさせていただくコードはこちら
宛先だけ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)
}
not75743not75743

実行結果

バージョン

$ go version
go version go1.19.4 linux/amd64

結果

$ go run main.go
200 OK
<!doctype html>
<html>
<head>
    <title>Example Domain</title>
... 略 ...
not75743not75743

httpリクエスト生成

main.go
	req, err := http.NewRequest("GET", "https://example.com", nil)
	if err != nil {
		log.Fatal(err)
	}

https://pkg.go.dev/net/http#NewRequest

変数宣言

httpリクエスト生成

  • (*Request, error)が返され、reqerrに格納

エラー処理

not75743not75743

httpリクエスト実行

main.go
	client := &http.Client{}
...
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}

https://pkg.go.dev/net/http#Client.Do

http.client構造体初期化

httpリクエスト実行(client.Do)

  • 引数にrequestが必要(http.newrequestで生成したもの)
  • (*Response, error)を返し、resperrに格納
  • 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.

not75743not75743

response.Body読み込み

main.go
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

https://pkg.go.dev/io/ioutil#ReadAll

なぜ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できず、コネクションの再利用ができないかららしい
https://qiita.com/hayabusa_3288/items/9fd2da8bc3bd6310d576

ioutilはdeprecated

ioパッケージを使うのが推奨らしいです
https://future-architect.github.io/articles/20210210/

つまり以下のように書き換えられます。

import (
	"io"
)

func main() {
...
	b, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
not75743not75743

response.Body出力

main.go
	fmt.Printf("%s", b)

https://pkg.go.dev/fmt

%sとは?

stringを表します。
%<記号>とすることで値をフォーマットできます
https://oohira.github.io/gobyexample-jp/string-formatting.html

フォーマットの一覧は以下を参照
https://pkg.go.dev/fmt#hdr-Printing

つまり今回は何をしているの?

string型で出力しています。
Readallしたものはbyte型であるため、変換する必要があります。

このスクラップは2023/01/02にクローズされました