目的
前回、GoとReact環境をdockerで構築
https://qiita.com/zukka/items/5a6831bef702d8c910e0
次は、フロント側のReact側からGoのAPIを呼び出して出力されたテキストをフロントに表示することを目標に。
GoでAPIを構築
webフレームワークGinを使う
GinはGo言語ベースのWebアプリケーションフレームワーク
軽量かつ実行速度が速いということが特徴
インストール
go-sampleというモジュール名で初期する
go mod init は新しいGoモジュールを初期化するためのコマンド
docker-compose run --rm go sh -c 'go mod init go-sample'
WEBフレームワークのginを取得する
docker-compose run --rm go sh -c 'go get -u github.com/gin-gonic/gin'
main.go作成
goフォルダ内にmain.goファイルを作成
main.goファイルとは
goプログラムを実行させるために必要なパッケージ
goでのパッケージとは
プログラムのグループ分けする機能
同じディレクトリにあるソースファイルの集合
モジュール性、カプセル化、分離されたコンパイル、再利用をサポートするもの
パッケージのルール
1.パッケージ == ディレクトリ
プログラムを実行させるためには「main」パッケージが必須
mainパッケージのmain関数を、 プログラムのエントリポイントとして処理
2.パッケージは名前を持つ
パッケージ名ルール
- 1つのディレクトリでは、1つのパッケージ名しか利用できない
- mainは特別なパッケージ名
- パッケージ名はディレクトリ名に依存しない
- パッケージ名はユニークでなくて良い
3.公開制限
- 外部に公開していい場合は名前の頭文字を大文字
- 非公開にしたい場合は名前の頭文字を小文字
main.goのソースコード
package main
import (
"log"
"github.com/gin-gonic/gin"
)
func main() {
log.Println("start server...")
r := gin.Default()
r.GET("/hello", func(context *gin.Context) {
context.JSON(200, gin.H{
"message": "Hello World!",
})
})
log.Fatal(r.Run(":3001"))
}
main.goを実行
docker-compose.ymlのgoセクションに次を追記
go:
container_name: go-api
build:
context: .
dockerfile: DockerfileGo
volumes:
- ./go:/api
command: sh -c "go run main.go" ← 追記
ports:
- 3001:3001
tty: true
確認
コンテナを起して、
http://localhost:3001/
にアクセスして出力を確認
{"message":"Hello World!"}
フロントでAPIを受け取る
reactのコンテナにaxiosをインストール
reactでAPIを受け取るためにHTTP クライアントaxiosをインストール
docker-compose run --rm react-app sh -c 'npm install axios'
API受信用のpageを作成
src/app/にapi-testフォルダを作成し、page.tsxを作成
Reactコンポーネント内の状態を管理する(変数)したい時はuseState
"use client";
import axios from "axios";
import { useState } from "react"; // コンポーネントの中で変数を扱うためにuseStateが必要
export default function Home() {
//変数messageを宣言、messageを更新する関数setMessage、初期値'test'をセット
const [message, setMessage] = useState('test');
const getData = async () => {
try {
const response = await axios.get("http://localhost:3001/hello");
setMessage(response.data['message']); //関数setMessageを実行(変数messageを更新)
} catch (error) {
console.error('Error fetching data:', error);
}
};
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={getData}
>
getDate
</button>
</div>
<p>{message}</p>
</main>
);
}
CORSエラー
このまま実行するとAPIがCORSエラーとなる。
CORSモジュールをインストール
docker-compose run --rm go sh -c 'go get -u github.com/gin-contrib/cors'
main.go修正
main.goファイルを次のように修正
package main
import (
"github.com/gin-gonic/gin"
"github.com/gin-contrib/cors"
"time"
"log"
)
func main() {
log.Println("start server...")
r := gin.Default()
// ここからCorsの設定
r.Use(cors.New(cors.Config{
// 許可したいアクセス元
AllowOrigins: []string{
"http://localhost:3000",
"http://localhost:3001",
},
// 許可したいHTTPメソッド
AllowMethods: []string{
"GET",
"OPTIONS",
},
// 許可したいHTTPリクエストヘッダ
AllowHeaders: []string{
"Access-Control-Allow-Credentials",
"Access-Control-Allow-Headers",
"Content-Type",
"Content-Length",
"Accept-Encoding",
"Authorization",
},
// cookieなどの情報の要否
AllowCredentials: true,
// preflightリクエストの結果をキャッシュする時間
MaxAge: 24 * time.Hour,
}))
r.GET("/hello", func(context *gin.Context) {
context.JSON(200, gin.H{
"message": "Hello World!",
})
})
log.Fatal(r.Run(":3001"))
}
動作確認
http://localhost:3000/api-test
にアクセス
getDataボタンをクリックして、Hello World!が表示される。