Go LangでWebAPIを作成するために、GolangでエンドポイントにアクセスしDBからデータを取得するでデータ取得の処理は確認できた。

リファクタリング

次に現状、main.goにすべての記述をしていたが、それぞれ簡単に責務ごとにフォルダを分けることにした。

分け方は、下記の通り。

db フォルダ:

  • データベース関連の処理: db フォルダは主にデータベースとのやり取りに関するコードを含みます。
  • データベースの初期化: db.go ファイルではデータベースの初期化と接続に関するコードがあります。
  • モデルの定義: データベースのテーブルに対応するモデルを定義します(例: db.Model)。
// db/db.go
package db

import (
	"fmt"
	"os"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DB *gorm.DB

type Model struct {
	gorm.Model
}

func InitDB() {
	dsn := os.Getenv("DB_CONNECTION_STRING")
	if dsn == "" {
		fmt.Println("DB_CONNECTION_STRING 環境変数が設定されていません")
		os.Exit(1)
	}

	var err error
	DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Printf("データベースへの接続に失敗しました: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("データベースに接続しました")
}

handlers フォルダ:

  • HTTP ハンドラとリクエスト処理: handlers フォルダは主に HTTP リクエストを処理し、それに対するレスポンスを生成するコードを含みます。
  • ルーティング: リクエストのルーティングやエンドポイントの定義が handlers.go にあります。
  • 特定の機能の処理: 例えば、user_handler.go ではユーザー関連の処理が定義されています。
// handlers/handlers.go
package handlers

import (
	"project-Backend/src/db"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

type User struct {
	db.Model // ここで埋め込みを行う

	Name     string
	Age      int
	IsActive bool
}

func HandleRequests() {
	http.HandleFunc("/users", FetchUsers)
	log.Fatal(http.ListenAndServe(":8081", nil))
}

func FetchUsers(w http.ResponseWriter, r *http.Request) {
	db := db.DB

	var users []User
	db.Find(&users)

	profJSON, err := json.Marshal(users)
	if err != nil {
		http.Error(w, "ユーザーデータのマーシャリングに失敗しました", http.StatusInternalServerError)
		return
	}

	fmt.Fprintf(w, string(profJSON))
}

main.go:

  • プログラムのエントリーポイントである main.go には、アプリケーションの起動や初期化といった主要な機能
// main.go
package main

import (
	"log"

	"project-Backend/src/db"
	"project-Backend/src/handlers"

	"github.com/joho/godotenv"
)

func init() {
	err := godotenv.Load()
	if err != nil {
		log.Fatal("Error loading .env file")
	}

	db.InitDB()
}

func main() {
	handlers.HandleRequests()
}

これで分かりやすくなった。

handlers フォルダを詳細に

FetchUsersもついでに分けることにする。

// handlers/user_handler.go
package handlers

import (
	"project-Backend/src/db"
	"encoding/json"
	"fmt"
	"net/http"
)

type User struct {
	db.Model

	Name     string
	Age      int
	IsActive bool
}

func FetchUsers(w http.ResponseWriter, r *http.Request) {
	db := db.DB

	var users []User
	db.Find(&users)

	profJSON, err := json.Marshal(users)
	if err != nil {
		http.Error(w, "ユーザーデータのマーシャリングに失敗しました", http.StatusInternalServerError)
		return
	}

	fmt.Fprintf(w, string(profJSON))
}
// handlers/handlers.go
package handlers

import (
	"log"
	"net/http"
)

func HandleRequests() {
	http.HandleFunc("/users", FetchUsers)
	log.Fatal(http.ListenAndServe(":8081", nil))
}

これでそれぞれ管理しやすくなった。