🦔

【GO】HTTPリクエストを送信しよう

に公開

Webにおけるデータ通信の仕組み

クライアントとサーバー

  • クライアント
    Webブラウザ(Google Chrome、Firefox、Safariなど)やスマートフォンアプリなど、ユーザーが操作する側のソフトウェアやデバイスを指します。

  • サーバー
    Webサイトのコンテンツ(HTML、CSS、JavaScript、画像など)やデータ(データベース)を保管し、クライアントからのリクエストに応じてそれらを提供するコンピューターやプログラムを指します。

このクライアントとサーバー間のデータのやり取りは、主に HTTP(Hypertext Transfer Protocol) というプロトコル(通信規約)に基づいて行われます

1. リクエストの送信(クライアント → サーバー)

ユーザーがWebブラウザでURLを入力したり、リンクをクリックしたりすると、クライアントはサーバーに対して「この情報が欲しい」という要求(リクエスト)を送信します。

リクエストには以下の情報が含まれます。

  • URL(Uniform Resource Locator)
    どのサーバーのどのリソース(Webページ、画像など)が欲しいのかを示すアドレス。

  • HTTPメソッド
    どのような操作をしたいのかを示す。
    例:GET(情報の取得)、POST(データの送信)、PUT、DELETEなど。

  • ヘッダー
    リクエストに関する追加情報(使用しているブラウザ、受け入れ可能なデータ形式、認証情報など)。

  • ボディ(任意)
    POSTメソッドなどで送信する実際のデータ(例:フォームの入力内容)。

2. レスポンスの受信(サーバー → クライアント)

サーバーはクライアントからのリクエストを受け取ると、そのリクエストを処理し、要求された情報や処理結果をクライアントに返します。これを「レスポンス」と呼びます。

レスポンスには以下の情報が含まれます。

  • HTTPステータスコード
    リクエストの処理結果を示す3桁の数字。
    例:200 OK(成功)、404 Not Found(リソースが見つからない)など。

  • ヘッダー
    レスポンスに関する追加情報(データの種類、最終更新日時、キャッシュ情報など)。

  • ボディ
    実際に返されるデータ本体。
    例:HTMLファイル、画像データ、JSON形式のデータなど。

3. クライアントでの表示・処理

クライアントはレスポンスを受け取ると、ボディに含まれるデータを解析し、次のような処理を行います。

  • HTMLをレンダリングして画面に表示
  • CSSでスタイルを適用
  • JavaScriptを実行して動的な操作やイベント処理

まとめ

GETリクエスト

まず、GoでHTTPリクエストを扱うには、標準ライブラリのnet/httpパッケージを使用します。
そして、GETリクエストを実行するには、http.Get()関数を使用します。
以下に例を示します

get_request.go
package main

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

func PerformGetRequest() {
	url := "https://example.com" // リクエストを送信するURL

	// GETリクエストを送信
	resp, err := http.Get(url) //指定されたurlへGETリクエストを送信。
	if err != nil {
		fmt.Printf("GETリクエストの送信中にエラーが発生しました: %v\n", err)
		return
	}
	defer resp.Body.Close() // レスポンスボディを必ずクローズ

	// レスポンスのステータスコードを確認
	fmt.Printf("ステータスコード: %d\n", resp.StatusCode)

	// レスポンスボディを読み込む 
	body, err := io.ReadAll(resp.Body) 
	if err != nil {
		fmt.Printf("レスポンスボディの読み込み中にエラーが発生しました: %v\n", err)
		return
	}

	// レスポンスボディの内容を表示(例として一部のみ表示)
	// レスポンスが500バイト未満の場合にインデックス範囲外エラーにならないように条件分岐を追加
	if len(body) > 500 {
		fmt.Printf("レスポンスボディの一部: %s...\n", body[:500])
	} else {
		fmt.Printf("レスポンスボディ: %s\n", body)
	}
}

POSTリクエスト

GETリクエストが主にサーバーから情報を取得するのに対し、POSTリクエストはデータをサーバーに送信するために使われます。例えば、フォームの送信、新しいリソースの作成、ファイルのアップロードなどがPOSTリクエストで行われます。以下に例を示します。

post_request.go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings" // リクエストボディの文字列を扱うために使用
)

func PerformPostRequest() {
	url := "https://httpbin.org/post" // テスト用のPOSTリクエスト受け付けエンドポイント

	// 送信するデータ(リクエストボディ)
	// 通常はJSONやフォームデータなどを送信します
	// ここでは例として単純な文字列を送信します
	data := `{"name": "Go Developer", "language": "Go"}`
	
	// リクエストボディをio.Readerの形式で準備
	// strings.NewReaderはstringをio.Readerに変換します
	bodyReader := strings.NewReader(data)

	// POSTリクエストを送信
	// 第3引数にコンテンツタイプを指定します
	resp, err := http.Post(url, "application/json", bodyReader)
	if err != nil {
		fmt.Printf("POSTリクエストの送信中にエラーが発生しました: %v\n", err)
		return
	}
	defer resp.Body.Close() // レスポンスボディを必ずクローズする

	// レスポンスのステータスコードを確認
	fmt.Printf("ステータスコード: %d\n", resp.StatusCode)

	// レスポンスボディを読み込む
	responseBody, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("レスポンスボディの読み込み中にエラーが発生しました: %v\n", err)
		return
	}

	// レスポンスボディの内容を表示
	fmt.Printf("レスポンスボディ: %s\n", responseBody)
}

今回はmain.goで呼び出す想定です。

main.go
package main

import (
	"fmt"
)

func main() {
	fmt.Println("--- GETリクエストの実行 ---")
	PerformGetRequest() // get_request.go にある関数を呼び出す

	fmt.Println("\n--- POSTリクエストの実行 ---")
	PerformPostRequest() // post_request.go にある関数を呼び出す
}

まとめ

Webにおけるデータ通信は、クライアント(例:ブラウザ)とサーバーの間で、HTTPプロトコルを用いて行われます。

  • クライアントは、HTTPリクエストを通じて「どんな情報が欲しいか」をサーバーに伝えます。
  • サーバーはそれに応じて、HTTPレスポンスとして必要な情報(HTML、JSONなど)を返します。
  • GET:データを「取得」するためのリクエスト。URLだけでデータを取得できる。
  • POST:データを「送信」するためのリクエスト。フォーム送信やAPIへのデータ登録で使う。
  • Goでの実装
    • http.Get():GETリクエストを送る関数。
    • http.Post():POSTリクエストを送る関数。Content-Type や io.Reader 形式のボディが必要。
    • io.ReadAll():レスポンスの内容を読み取る際に使用。

Discussion