LoginSignup
2
3

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"
}

完成!!!

2
3
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
2
3