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

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

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

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

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

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

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

GET についてのHTTPリクエストは下記の記事で紹介しています。

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

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

もりぴをフォローする

HTTPリクエストのPOSTとは?

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

GET ではURLの後ろにサーバーに対してのお願いする情報が表記されています。

対して POST は、例えばお問い合わせフォームの個人情報やパスワードなど表面的に見えてはいけない情報をサーバーに送るのに適したリクエスト方法です。

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

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

POSTで指定したURLの内容を取得する

POST によるサーバーへのリクエストの基本です。

今回は仮想の "https://example.com" を使用しますので、出力結果は単純に Body の内容が出力されるだけですので割愛します。

package main

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

func main() {
    // POSTメソッド
    // url.Values{}でPOSTで送信する入れ物を準備
    ps := url.Values{}

    // Add()でPOSTで送信するデータを作成
    ps.Add("id", "1")
    ps.Add("name", "もりぴ")
    // 特殊文字や日本語をエンコード
    fmt.Println(ps.Encode())

    // http.PostForm()でPOSTメソッドを発行
    res, err := http.PostForm("http://example.com", ps)
    if err != nil {
        log.Fatal(err)
    }
    // deferでクローズ処理
    defer res.Body.Close()
    // Bodyの内容を読み込む
    body, _ := io.ReadAll(res.Body)
    // Bodyの内容を出力する
    fmt.Print(string(body))
}
もりぴ
もりぴ

それでは、今回のプログラムの流れを確認していきましょう!

POSTによるHTTPリクエストでのプログラムの流れ
  • url.Values{}POST で送信する入れ物を準備
  • Add()POST で送信するデータを作成
  • .Encode() で特殊文字や日本語をエンコード
  • http.PostForm()POST メソッドを発行
  • defer res.Body.Close() でクローズ処理
  • io.ReadAll(res.Body) でBodyの内容を読み込む

という流れです。

ioutilでの注意点がありますので、こちらで確認してください。

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

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

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

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "net/url"
)

type Account struct {
    ID       string
    PassWord string
}

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

    //URLの後ろクエリの確認
    reference, _ := url.Parse("index/lists?id=1")

    //Postなのでデータを格納
    AccountData := &Account{ID: "ABC0123", PassWord: "testpass"}
    // json.Marshal()でJSON形式に
    data, _ := json.Marshal(AccountData)

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

    //POSTの場合は見えないようにBodyにデータを入れる
    //bytes.NewBuffer()でリクエストの領域を作成
    req, _ := http.NewRequest("POST", endpoint, bytes.NewBuffer(data))

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

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

    //クエリを追加
    q.Add("name", "test")

    //encodeしてからURLに追加
    fmt.Println(q.Encode())

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

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

    //結果を変数に代入
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }

    // deferでクローズ処理
    defer resp.Body.Close()

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

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

以上になります。

POST でHTTPリクエストする際に、全く同じではありませんがパターン化しているプログラムの流れです。

【最後に】実際にコードを記述して試してみよう!

今回は「net/httpを利用してGoでPOSTによるHTTPリクエストの基本」についてお伝えしてきました。

私もそうでしたが、コードを見ただけではなかなか理解しずらいのがネットワーク関連だと思います。

コードを書いてデバックができる方はデバックしながら、私みたいにデバックがよくわからない方は、fmt.Println() を使用して変数の値を確認してみると理解は早まると思います。

もりぴ
もりぴ

理解がちょっと怪しいな?

と感じるのであれば、実際に動いているWEBアプリのプログラムコードを写経してみることをおすすめします。

悩みも多くなると思いますが、悩んだ分だけ理解も深まりますよ!

comment

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