net/httpを利用してGoでGETによるHTTPリクエストの基本

Go言語
この記事は約10分で読めます。
Go初学者
Go初学者

GoでGETによるHTTPリクエストの基本を知りたいな…

この記事ではGoでGETによるHTTPリクエストの基本を理解できます!
  • GET について
  • net/http でGETによるHTTPリクエストの基本
  • net/http でGETによるHTTPリクエストの応用

今回はGo言語の標準パッケージ・net/http を利用して GET によるHTTPリクエストする方法についてです。

WEBアプリ開発において、サーバーへのリクエストは知っておかなければいけいでしょう。

今回は GET による基本的なリクエストの方法と、私がGo言語のプログラムを写経していて見かけたパターンを応用編として紹介していきます。

もりぴ
この記事を書いた人

XHTML1.0時代にHTML&CSSを勉強した経験あり。無趣味だった私が2020年5月からプログラミング学習を開始し現在も挫折せずに趣味で学習を楽しんでいる51歳。プログラミングの楽しさをブログを通してお伝えしていきます。

もりぴをフォローする

HTTPリクエストのGETとは?

HTTPリクエストはサーバーに対してのお願いで、GET はサーバーにお願いするための値の渡し方の種類です。

GET の特徴としては、URLの後ろに値を付けてサーバーにお願いします。

もりぴ
もりぴ

例えば、Googleで「翻訳」を検索した際のURLを見てみましょう。

https://www.google.com/search?q=%E7%BF%BB%E8%A8%B3&oq=%E7%BF%BB%E8%A8%B3&aqs=chrome.0.69i59.2044j0j7&sourceid=chrome&ie=UTF-8

URLの後ろの…

search?q=%E7%BF%BB%E8%A8%B3&oq=%E7%BF%BB%E8%A8%B3&aqs=chrome.0.69i59.2044j0j7&sourceid=chrome&ie=UTF-8

この部分がサーバーにお願いしている部分になります。

GET はURLの後ろにお願いする値の情報が全て表記されているので、メールアドレスやパスワードの情報を送信するお問い合わせフォームでの使用は厳禁です。

パソコン君
パソコン君

お問合フォームなどは POST を使うよ!

net/httpでGETによるHTTPリクエストの基本

それでは、Goの標準パッケージ・net/httpGET によるHTTPリクエストの基本についてプログラムで確認していきます。

GETで指定したURLの内容(Body)を取得する

URLを指定して、そのURLの内容(Body)を見てみましょう。

package main

import (
    "fmt"
    "io"
    "net/http"
)

func main() {
    // http.Get()でURLの情報を取得
    res, _ := http.Get("https://example.com")
    // deferで先に閉じる処理をしておく
    defer res.Body.Close()
    // 取得したURLの内容を読み込む
    body, _ := io.ReadAll(res.Body)
    // 取得した情報は[]byteなのでstringに型変換
    fmt.Print(string(body))
}
// 出力結果
$ go run main.go
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;
        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        div {
            margin: 0 auto;
            width: auto;
        }
    }
    </style>    
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

"https://example.com"Body の内容を出力することができました。

もりぴ
もりぴ

それでは、今回のプログラムを確認していきます。

GETによるHTTPリクエストの基本的なプログラムの流れ
  • http.Get("https://example.com") で情報を取得
  • defer res.Body.Close() で次の行で Body を読み込むので defer で閉じる処理を実行
  • io.ReadAll(res.Body)Body の内容を読み込む
  • 取得した情報は []byte なので fmt.Print(string(body))string に型変換

という流れです。

ioutilでの注意点

もりぴ
もりぴ

io.ReadAll() で注意しなければならないことがあります!

通常であれば、io.ReadAll() の箇所は ioutil.ReadAll() と記述されていましたがGoのバージョン 1.16 から変更になりました。

もりぴ
もりぴ

今回の記事では io.ReadAll() で記述しました。Goのバージョンが 1.16 以前の方は ioutil.ReadAll() で記述しましょう。

http.Get()で得られる情報を確認する

http.Get() では Body の情報だけでなく、いろいろな情報が取得できます。

package main

import (
	"fmt"
	"net/http"
)

func main() {
    res, _ := http.Get("https://example.com")

    fmt.Println(res.StatusCode)  // HTTPレスポンスステータス
    fmt.Println(res.Proto)  // HTTPプロトコル
    fmt.Println(res.Header["Date"])  // データを取得した日付と時間
    fmt.Println(res.Header["Content-Type"])  // コンテンツのタイプ
    fmt.Println(res.Request.Method)  // GETかPOST
    fmt.Println(res.Request.URL)  // URL
}
// 出力結果
$ go run main.go
200
HTTP/2.0
[Tue, 07 Sep 2021 23:49:16 GMT]
[text/html; charset=UTF-8]
GET
https://example.com

http.Get() でデータが取得できることが確認できましたので、あなたのアプリ開発で必要な情報やサーバーの情報取得に役立てていきましょう。

net/httpでGETによるHTTPリクエストの応用

今度は実際に GET でサーバーへ値を渡す処理をするプログラムを確認していきましょう。

プログラムの詳細はコメントでご確認ください。

package main

import (
    "fmt"
    "io"
    "net/http"
    "net/url"
)

func main() {
    // uri.Parse() 正しいURLか確認
    base, _ := url.Parse("http://example.com/")

    //クエリの確認
    reference, _ := url.Parse("/test?id=1")

    //クエリを貼付したURLを生成する
    endpoint := base.ResolveReference(reference).String()

    //リクエストを作成 GETの第3引数はnil
    req, _ := http.NewRequest("GET", endpoint, nil)

    //requestにheaderをつける
    req.Header.Add("Content-Type", `application/json"`)

    //URLのクエリを確認
    q := req.URL.Query()

    //クエリを追加
    q.Add("user", "morip")

    //encodeしてからURLに戻す
    req.URL.RawQuery = q.Encode()

    //クライアントを作成
    var client *http.Client = &http.Client{}

    //結果
    resp, _ := client.Do(req)

    //読み込み
    body, _ := io.ReadAll(resp.Body)

    //出力
    fmt.Println(string(body))
}

今回のプログラムで得られる出力結果は、先程の "https://example.com"Body と同じ内容ですので割愛いたします。

あなたがGo言語でWEBアプリのプログラムコードを写経する時に、おそらくこのコードの流れを見ることがるでしょう。

今回はクエリの値を簡易的なものにしましたが、これを実際のサーバーの値にすることで GET でのHTTPリクエストを可能にするはずです。

各変数にどんな値が代入されているかは、デバックや fmt.Println() を使用して確認してみましょう。

【最後に】ネットワーク関連は難しい…

他のプログラミング言語でHTTPリクエストを行ったことがある方には難しくないでしょうが、私はネットワーク関連の知識が乏しいため理解に苦しみました。

あるWEBアプリのコードを写経して意味が全然わからなくて困りましたが、実際にプログラムのコードを書いて動きを確認することで、若干ですが理解に一歩近づけたような気がします。

特に変数にどんな値が代入されているか、fmt.Println() で確認することをおすすめいたします。

次は POST についてお伝えしていきます。

comment

タイトルとURLをコピーしました