見出し画像

Goからリクエストを送りたい

はじめに

Goをというよりどの言語を使っていてもそこからリクエストを送りたいということはあると思います。自分もGoのサーバーから別のGoサーバーへリクエストを送りたいという場面に出くわしてリクエストを送る方法を調べたのでその方法例を通して紹介します。

今回のシチューエーション

Goでサーバー・クライアントを用意してGet・Postリクエストを送ってみます。

サーバー実装

あまり難しい例は必要ないので簡単なものを作っておきます。フレームワークとしてfiberを使っています。

package main

import (
	"fmt"

	"github.com/gofiber/fiber/v2"
)

func main() {
	app := fiber.New()

	app.Get("/", func(c *fiber.Ctx) error {
		return c.JSON(fiber.Map{
			"name": "get",
		})
	})

	app.Post("/", func(c *fiber.Ctx) error {
		fmt.Printf("header %s\n", c.Get("Content-Type"))
		fmt.Printf("body %s\n", c.Body())
		return c.JSON(fiber.Map{
			"name": "post",
		})
	})

	app.Listen("localhost:3000")
}

Getに関してはリクエストがくるとgetを返しているだけでPostに関しては受け取ったヘッダーのContent-TypeとBodyを出力し、postと返します。

1. Getリクエストを送る

まずGetを送ってみます!

以下のコードで送ることができます。

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

type Response struct {
	Name string `json:"name"`
}

func main() {
	// url指定
	url := "http://localhost:3000"

	// リクエスト作成
	res, _ := http.Get(url)

	// 読み込み
	byteArray, err := ioutil.ReadAll(res.Body)
	if err != nil {
		fmt.Println(err)
	}
	bytes := []byte(byteArray)
	var response Response
	err = json.Unmarshal(bytes, &response)
	if err != nil {
		fmt.Printf("error unmarshal %s", err)
	}
	fmt.Println(response)
}

コードの内容はコメントに書いている通りなのですがリクエストを作成してから送信を行なっています。見た感じhttp.Get(url)の部分が実行された時点でリクエストが送信されているみたいです。

読み込み以降は帰ってきたbody部を読み込んでからレスポンスの構造体に当てはめてから出力しています。

実行結果は以下のようになりました。

{get}

2. Postリクエストを送る パターン1

簡単な方で一つ紹介します!コードは以下です。

・先程のResponse構造体がRequestという名前に変わっています

package main

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

type Request struct {
	Name string `json:"name"`
}

func main() {
	// url指定
	url := "http://localhost:3000"

	// ボディ作成
	reqBody := Request{
		Name: "名前",
	}
	jsonValue, _ := json.Marshal(reqBody)
	resp, _ := http.Post(url, "application/json", bytes.NewBuffer(jsonValue))

	// 読み込み
	byteArray, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
	}
	bytes := []byte(byteArray)
	var response Request
	err = json.Unmarshal(bytes, &response)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(response)
}

Postで名前が必要なのでまずはreqBodyという名前でRequestの構造体を作成し名前を入れています。その後にJson形式に直しています。

	resp, _ := http.Post(url, "application/json", bytes.NewBuffer(jsonValue))

この行がポイントとなる部分で引数として最初にurl、次にcontentType、最後に入れたいbodyを入れています。読み込み部はGetと一緒なので解説は省きます。

実行結果は以下のようになりました。

// client側
{post}

// server側
header application/json
body {"name":"名前"}

3. Postリクエストを送る パターン2

2つ目のパターンです。ヘッダーが複数ある場合はカスタムしたい場合はこちらがいいような気がします。コメントに書いてあるのですがリクエスト送信とコメントで書いている時点で送られています。

package main

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

type Request struct {
	Name string `json:"name"`
}

func main() {
	// url指定
	url := "http://localhost:3000"

	// リクエスト作成
	client := &http.Client{}

	// ヘッダー作成
	header := http.Header{}
	header.Add("Content-Type", "application/json")

	// ボディ作成
	reqBody := Request{
		Name: "名前",
	}
	jsonValue, _ := json.Marshal(reqBody)

	req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonValue))
	req.Header = header

	// リクエスト送信
	resp, _ := client.Do(req)

	// 読み込み
	byteArray, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
	}
	bytes := []byte(byteArray)
	var response Request
	err = json.Unmarshal(bytes, &response)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(response)
}

パターン1と比べて記述量自体は増えていますがヘッダーの付与が自由にできたりリクエストを作ってから任意の時点で送信ができたりと自由度は高まっているとは思います。

まとめ

Goからリクエストを送信する方法を紹介しました。方法も複数あるので場面によって使い合わせて送ってください!

この記事が気に入ったらサポートをしてみませんか?