10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Go+TypeScript】バックエンドとフロントエンドの疎通まで

Last updated at Posted at 2023-06-27

はじめに

個人アプリを作る機会が増えてきたので、バックエンドとフロントエンド間の疎通までを簡単にまとめてみます。疎通に必要なcors設定についても触れていきます。

環境構築

以前に投稿した記事を元に作成しています。

バックエンドの実装

今回はユーザー作成機能とユーザー取得機能を実装することにします。

モデルの作成

go/src/models/model.go
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にまとめてしまいます。

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ができたら以下のファイルを作成します。

go/src/middleware/cors.go
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のサーバを再起動するだけで設定できてしまいます。

go/src/main.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を実行し、指定のユーザーデータを取得するように実装しています。

reactapp/src/components/pages/Top.tsx

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です。

image.png

おわりに

cors設定が簡単でした。

10
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?