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))
}
これでそれぞれ管理しやすくなった。