go初期設定
go言語のインストールはこちらから
インストール出来たら.
mkdir myproject
cd myproject
go mod init example.com/myproject
go get -u github.com/gin-gonic/gin
go get -u github.com/joho/godotenv
go get -u github.com/jackc/pgx/v4
ファイル構造
C:.
│ .env
│ go.mod
│ go.sum
│ main.go
│
├─config
│ config.go
│
├─controllers
│ user_controller.go
│
├─database
│ database.go
│
├─models
│ user.go
│
├─repositories
│ user_repository.go
│
├─routers
│ routre.go
│
└─services
user_service.go
実際のコード
main.go
main.goは今回のAPIのエントリーポイントの役割をしている.
main.go
package main
import (
"log"
"example.com/myproject/config"
"example.com/myproject/database"
"example.com/myproject/routers"
"github.com/gin-gonic/gin"
)
func main() {
// 環境変数の読み込み
config.LoadConfig()
// データベースの初期化
database.InitDB()
// Ginのデフォルトのルーターを作成
r := gin.Default()
// ルーティングの設定
routers.SetupRouter(r)
// サーバーをポート8000で起動
r.Run(":8000")
// サーバーの起動をログに記録
log.Println("Server started on :8000")
}
config.go
config.goは、アプリケーションの設定を管理するためのものであり,今回は.envファイルから環境変数を読み込み、アプリケーションで使用できるようにしている.
config.go
package config
import (
"log"
"os"
"github.com/joho/godotenv"
)
// LoadConfig は.envファイルから設定をロードする
func LoadConfig() {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
}
// GetEnv は環境変数を取得する
func GetEnv(key string) string {
return os.Getenv(key)
}
user_controller.go
user_controller.goは,ユーザーからのHttpリクエストを処理するものである.
user_controller.go
package controllers
import (
"net/http"
"example.com/myproject/models"
"example.com/myproject/services"
"github.com/gin-gonic/gin"
)
// 全てのユーザーデータの取得
func GetUsers(c *gin.Context) {
users, err := services.GetUsers()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, users)
}
// 指定されたIDのユーザーデータの取得
func GetUser(c *gin.Context) {
id := c.Param("id")
user, err := services.GetUser(id)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, user)
}
// 新しいユーザーデータの作成
func CreateUser(c *gin.Context) {
var user models.User
if err := c.BindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := services.CreateUser(user); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, gin.H{})
}
// 指定されたIDのユーザーデータの更新
func UpdateUser(c *gin.Context) {
id := c.Param("id")
var user models.User
if err := c.BindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := services.UpdateUser(id, user); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{})
}
// 指定されたIDのユーザーデータの削除
func DeleteUser(c *gin.Context) {
id := c.Param("id")
if err := services.DeleteUser(id); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{})
}
database.go
database.goは,データベースとの接続と必要な場合はテーブルの作成をするものである.
database.go
package database
import (
"context"
"log"
"example.com/myproject/config"
"github.com/jackc/pgx/v4"
)
// DB はデータベースへの接続を保持します。
var DB *pgx.Conn
// InitDB はデータベースを初期化し、接続を確立します。
func InitDB() {
var err error
// DATABASE_URL環境変数からdatabaseのURIを取得
dsn := config.GetEnv("DATABASE_URL")
// pgxライブラリを使用して、DSNを使用してデータベースに接続
DB, err = pgx.Connect(context.Background(), dsn)
if err != nil {
log.Fatalf("Unable to parse DSN: %v\n", err)
}
// ユーザーのテーブルが存在しない場合は作成
createTableSQL := `
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name TEXT,
email TEXT
);`
_, err = DB.Exec(context.Background(), createTableSQL)
if err != nil {
log.Fatalf("Failed to create table: %v\n", err)
}
}
user.go
user.goは,User構造体を定義し,JSON形式での表現とデータベース内のカラムとのマッピングを行うためのタグも含めている.
user.go
package models
// User はユーザーを表すデータ構造体
type User struct {
ID int `json:"id" db:"id"` // ユーザーのID
Name string `json:"name" db:"name"` // ユーザーの名前
Email string `json:"email" db:"email"` // ユーザーのメールアドレス
}
user_repositories.go
user_repositories.goは,ユーザーに関するデータベース操作を行うためのリポジトリを定義したもので,データベースの操作を行うもの.
user_repositories.go
package repositories
import (
"context"
"example.com/myproject/database"
"example.com/myproject/models"
)
// すべてのユーザーをデータベースから取得
func GetAllUsers() ([]models.User, error) {
var users []models.User
query := "SELECT id, name, email FROM users"
rows, err := database.DB.Query(context.Background(), query)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var user models.User
if err := rows.Scan(&user.ID, &user.Name, &user.Email); err != nil {
return nil, err
}
users = append(users, user)
}
return users, nil
}
// 指定されたIDのユーザーをデータベースから取得
func GetUser(id string) (models.User, error) {
var user models.User
query := "SELECT id, name, email FROM users WHERE id = $1"
err := database.DB.QueryRow(context.Background(), query, id).Scan(&user.ID, &user.Name, &user.Email)
if err != nil {
return models.User{}, err
}
return user, nil
}
// 新しいユーザーをデータベースに作成
func CreateUser(user models.User) error {
query := "INSERT INTO users (name, email) VALUES ($1, $2)"
_, err := database.DB.Exec(context.Background(), query, user.Name, user.Email)
if err != nil {
return err
}
return nil
}
// 指定されたIDのユーザーをデータベースで更新
func UpdateUser(id string, user models.User) error {
query := "UPDATE users SET name = $1, email = $2 WHERE id = $3"
_, err := database.DB.Exec(context.Background(), query, user.Name, user.Email, id)
if err != nil {
return err
}
return nil
}
// 指定されたIDのユーザーをデータベースから削除
func DeleteUser(id string) error {
query := "DELETE FROM users WHERE id = $1"
_, err := database.DB.Exec(context.Background(), query, id)
if err != nil {
return err
}
return nil
}
router.go
router.goは,SetupRouter関数がGinエンジンを受け取り、HTTPリクエストとそれに対応するコントローラーの関連付けを行うものである.
router.go
package routers
import (
"example.com/myproject/controllers"
"github.com/gin-gonic/gin"
)
// ルーティングを設定
func SetupRouter(r *gin.Engine) {
// GETリクエストでのユーザー取得エンドポイントを設定し、controllers.GetUsers関数を実行する
r.GET("/users", controllers.GetUsers)
// GETリクエストでの特定のユーザー取得エンドポイントを設定し、controllers.GetUser関数を実行する
r.GET("/users/:id", controllers.GetUser)
// POSTリクエストでのユーザー作成エンドポイントを設定し、controllers.CreateUser関数を実行する
r.POST("/users", controllers.CreateUser)
// PUTリクエストでのユーザー更新エンドポイントを設定し、controllers.UpdateUser関数を実行する
r.PUT("/users/:id", controllers.UpdateUser)
// DELETEリクエストでのユーザー削除エンドポイントを設定し、controllers.DeleteUser関数を実行する
r.DELETE("/users/:id", controllers.DeleteUser)
}
user_service.go
user_service.goはuser_controllerから呼び出されるのに対して、データベース操作を抽象化し、ビジネスロジックとデータアクセスを分離するものである.
user_service.go
package services
import (
"example.com/myproject/models"
"example.com/myproject/repositories"
)
// すべてのユーザーを取得
func GetUsers() ([]models.User, error) {
return repositories.GetAllUsers()
}
// 指定されたIDのユーザーを取得
func GetUser(id string) (models.User, error) {
return repositories.GetUser(id)
}
// 新しいユーザーを作成
func CreateUser(user models.User) error {
return repositories.CreateUser(user)
}
// 指定されたIDのユーザーを更新
func UpdateUser(id string, user models.User) error {
return repositories.UpdateUser(id, user)
}
// 指定されたIDのユーザーを削除
func DeleteUser(id string) error {
return repositories.DeleteUser(id)
}
.env
.env
DATABASE_URL=uri
実行
実行コマンド
go run main.go
動作確認
1.PostmanでかきのURLにPOSTしてみよう
http://localhost:8000/users
2.jsonのテンプレート
{
"name": "test_name",
"email": "test_mail"
}
完成!!!