🐒
【Go】GinでCRUDなREST API作ってみた #1 (環境設定とモデルのマイグレーションまで)
Itemオブジェクトの作成(Create)、読み込み(Read)、更新(Update)、削除(Delete)を行うAPIをginフレームワーク、postgresqlを使用して作りました。
さらに、pgAdmin(postgresql用のGUI管理ツール)を使用し、データベースサーバーを作成しました。
はじめに
Ginフレームワークの特徴
- 軽量で高速なパフォーマンス
- 基数木(redix tree)を元にしたルーティング、小さなメモリフットプリント、リフレクションなし、予測可能な API 性能などの特徴があります。
- ミドルウェアのサポート
- 受信したHTTPリクエストをミドルウェアのチェーンと最終的なアクションによりハンドリングできます。たとえば、ロガー、認証、GZIP、さらに DB へのメッセージのポストなどが可能です。
- クラッシュフリー
- HTTPリクエスト中に発生したパニcをキャッチし、回復することが可能で、サーバーが常に利 用可能な状態になる
などなどGinは素晴らしい特徴を兼ね備えています。
使用するライブラリ紹介
- godotenv
goプロジェクトで.envを使用して環境変数を管理するためのライブラリ。
今回はデータベースサーバーの環境変数などを.envファイルで管理します。
golangのORM(Object Relational mapping)ライブラリ。
特徴は、アソシエーション機能、イベントフック、トランザクションなどが提供されています。
プロジェクトの構造
.
├── controllers
│ └── item_controller.go
├── docker-compose.yaml
├── dto
│ └── item_dto.go
├── go.mod
├── go.sum
├── infra
│ ├── db.go
│ └── initializer.go
├── main.go
├── migrations
│ └── migration.go
├── models
│ └── item.go
├── repositories
│ └── item_repository.go
└── services
└── item_service.go
- 3層アーキテクチャ
- Controller
- リクエストデータのハンドリングやレスポンスの設定
- Service
- 実現したい機能(ビジネスロジック)の実装
- Repository
- データの永続化やデータソースとのやりとり
- Controller
プロジェクトの作成
- go.modファイルを以下のコマンドで作成する
sh
$ go mod init <プロジェクト名>
go.modファイルは使用されるモジュールの依存関係を管理するファイルです
- ginのインストール
sh
$ go get -u github.com/gin-gonic/gin
- main.goをプロジェクトのルートに作成
データベース環境の構築
- docker-compose.yamlを使って、データベース環境の構築
docker-compose.yaml
version: "3.8"
services:
postgres:
image: postgres:16-alpine
container_name: postgres
ports:
- 5433:5432
volumes:
- ./docker/postgres/init.d:/docker-entrypoint-initdb.d
- ./docker/postgres/pgdata:/var/lib/postgresql/data
environment:
POSTGRES_USER: ginuser
POSTGRES_PASSWORD: ginpassword
POSTGRES_INITDB_ARGS: "--encoding=UTF-8"
POSTGRES_DB: fleamarket
hostname: postgres
restart: always
user: root
pgadmin:
image: dpage/pgadmin4
restart: always
ports:
- 81:80
environment:
PGADMIN_DEFAULT_EMAIL: gin@example.com
PGADMIN_DEFAULT_PASSWORD: ginpassword
volumes:
- ./docker/pgadmin:/var/lib/pgadmin
depends_on:
- postgres
- docker-composeを起動
sh
$ docker compose up -d
- pgAdmin 4にログイン
docker-compose.yamlで指定したポート番号(上記の記述だと81番ポート)を指定してブラウザでログイン画面に行きます。docker-compose.yamlで指定したemailアドレスとパスワードでログイン。 - データベースサーバーの作成
ログイン後このような画面に遷移するかと思います。
この画面の「新しいサーバーを追加」をクリックし、新しいサーバーの登録を行なっていきます
docker-compose.yaml通りに設定し終えたら、保存ボタンを押します。
しっかり、作成したデータベースサーバーが登録されています。
データベースとの接続設定
- gorm,sqlite用のドライバー、postgressql用のドライバーのインストール
sh
$ go get -u gorm.io/gorm
$ go get -u gorm.io/driver/sqlite
$ go get -u gorm.io/driver/postgres
- godotenvパッケージのインストール
sh
$ go get github.com/joho/godotenv
- .envファイルの作成
.env
DB_HOST=localhost
DB_USER=ginuser
DB_PASSWORD=ginpassword
DB_NAME=fleamarket
DB_PORT=5433
- initializer.goで.envファイルのロード機能を記述
infra
package infra
import (
"log"
"github.com/joho/godotenv"
)
func Initialize() {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
}
- db.goにデータベースのセットアップを記述
/infra/db.go
package infra
import (
"fmt"
"log"
"os"
"github.com/joho/godotenv"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func SetupDB() *gorm.DB {
dsn := fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Tokyo",
os.Getenv("DB_HOST"),
os.Getenv("DB_USER"),
os.Getenv("DB_PASSWORD"),
os.Getenv("DB_NAME"),
os.Getenv("DB_PORT"),
)
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic("Failed to connect database")
}
log.Println("Database connection successful!")
return db
}
モデルの作成
item.goにItem構造体(CRUD操作の対象モデル)を記述
/models/item.go
package models
import "gorm.io/gorm"
type Item struct {
gorm.Model
Name string `gorm:"not null"`
Price uint `gorm:"not null"`
Description string
SoldOut bool `gorm:"not null;default:false"`
}
gorm.ModelにはID、CreatedAt、UpdatedAt、DeletedAt属性が含まれている。
マイグレーション
- migration.goファイルを作成
/migrations/migration.go
package main
import (
"<プロジェクト名>/infra"
"<プロジェクト名>/models"
)
func main() {
infra.Initialize()
db := infra.SetupDB()
if err := db.AutoMigrate(&models.Item{}); err != nil {
panic("Failed to migrate database")
}
}
- コマンドでマイグレーションの実行
sh
$ go run migrations/migration.go
終わりに
次回からAPI構築の記事を書いていきたいと思います
参考
今回はYu Shinozakiさんの「Gin入門 Go言語ではじめるサーバーサイド開発」というUdemyの講義を見ながら作成いたしました。とてもわかりやすくておすすめです!
ginフレームワークの公式ドキュメント
Discussion