はじめに
個人アプリを作る機会が増えてきたので、バックエンドとフロントエンド間の疎通までを簡単にまとめてみます。疎通に必要なcors設定についても触れていきます。
環境構築
以前に投稿した記事を元に作成しています。
バックエンドの実装
今回はユーザー作成機能とユーザー取得機能を実装することにします。
モデルの作成
package models
import "time"
type User struct {
ID uint `gorm:"primaryKey"`
Name string
Email string
Password string
CreatedAt time.Time
UpdatedAt time.Time
}
main.goの作成
今回はmain.goにまとめてしまいます。
package main
import (
"github.com/gin-gonic/gin"
"sample_go/models"
"sample_go/middleware"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"net/http"
"time"
)
var db *gorm.DB
func main() {
// GORMの初期化
dsn := "root:password@tcp(コンテナ名:3306)/.envで指定したdb名?charset=utf8mb4&parseTime=True&loc=Local"
var err error
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("Failed to connect to database")
}
err = db.AutoMigrate(&models.User{})
if err != nil {
panic("Failed to migrate database")
}
// Ginのルーターの初期化
router := gin.Default()
router.Use(middleware.Cors())
router.GET("/users/:id", getUser)
router.POST("/users", createUser)
router.Run(":8000")
}
func getUser(c *gin.Context) {
userID := c.Param("id")
var user models.User
result := db.First(&user, userID)
if result.Error != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
return
}
c.JSON(http.StatusOK, user)
}
func createUser(c *gin.Context) {
var user models.User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
result := db.Create(&user)
if result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create user"})
return
}
c.JSON(http.StatusCreated, user)
}
cors設定について
予め設定しておかないと、フロントでaxiosを叩いても以下のエラーが発生します。
Access to XMLHttpRequest at 'http://localhost:8000/users/1' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
設定についてはこちらの記事を参考にさせていただきました。
$ docker exec -it コンテナ名 sh
$ go get "github.com/gin-contrib/cors"
go getができたら以下のファイルを作成します。
package middleware
import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"time"
)
func Cors() gin.HandlerFunc {
return cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:3000"},
AllowMethods: []string{"GET", "POST", "PUT", "OPTIONS"},
AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
})
}
ここで作成したcors.goをmain.goでimportして使います。
main.goに以下を加え、goのサーバを再起動するだけで設定できてしまいます。
import (
"github.com/gin-gonic/gin"
"sample_go/middleware"
)
router := gin.Default()
router.Use(middleware.Cors())
Postmanで疎通確認
以下のJSONデータをPOST /usersにリクエストしてデータが作成されていればOKです。
{
"name": "John Doe",
"email": "johndoe@example.com",
"password": "secretpassword"
}
GET /users/1にリクエストして先ほど作成したデータが返ってくることも確認します。
フロントエンドの実装
一部省略します。
ここでは画面にアクセスした際にuseEffectでaxiosを実行し、指定のユーザーデータを取得するように実装しています。
import axios from 'axios';
interface UserData {
ID: number;
Name: string;
Email: string;
Password: string;
CreatedAt: string;
UpdatedAt: string;
}
export const Top = memo(() => {
const [user, setUser] =useState<UserData | null>(null)
useEffect(() => {
const getUserInfo = async () => {
try {
const res = await axios.get('http://localhost:8000/users/1');
setUser(res.data);
// console.log(res.data)
} catch (error) {
console.log(error);
}
};
getUserInfo();
}, []);
return (
<>
<Box bg="red.400" textAlign="center">{user?.Name}</Box>
<Box bg="red.400" textAlign="center">{user?.Email}</Box>
<Box bg="red.400" textAlign="center">{user?.Password}</Box>
</>
)})
動作確認
localhost:3000にアクセスし、サンプルデータのユーザ名などが画面に表示されていればOKです。
おわりに
cors設定が簡単でした。