1. Go LangでWebAPIを作成するために、GolangでMySQLに接続する
  2. Go LangでWebAPIを作成するために、Golangでサーバーを立ち上げる

DBと接続することはできたし、サーバーを立ち上げることに成功した。

User情報を取得するAPIを作成する

次は、特定のエンドポイントにアクセスした際に、DBからデータを取得する。

具体的にはhttp://localhost:8081/usrsにアクセスした際にusersテーブルのデータを取得できるようにしたい。

エンドポイントを作成する

まずはhttp://localhost:8081/usrsのエンドポイントを作成する。

func sample(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Welcome to the sample!")
	fmt.Println("Endpoint Hit: sample")
}

func handleRequests() {
	http.HandleFunc("/sample", sample)
	log.Fatal(http.ListenAndServe(":8081", nil))
}

handleRequestsmain関数の中で実行すればhttp://localhost:8081/usrsにアクセスした際に

Welcome to the sample

と表示されるようになった。

ちになみに、

	fmt.Fprintf(w, "Welcome to the sample!")

上記のwが謎で調べてみたところ、

w を使用して Write メソッドを呼び出すことで、HTTPレスポンスの本文をクライアントに送信することができます。fmt.Fprintf(w, “Welcome to the sample!”) は、fmt.Fprintf 関数を使用してフォーマットされた文字列を w.Write を介してクライアントに送信しています。

とのことだった。

いまいち理解しかねるけれど、なんとなく必要なことは分かった。

DBのデータをフェッチする

次にhttp://localhost:8081/usrsにアクセスした際にDBの値を返すようにしてみる。

まずはDBに接続する関数を作成する。 これは前回も作成した。

func dbInit() *gorm.DB {
	dsn := "root:password@tcp(127.0.0.1:3306)/project?charset=utf8mb4&parseTime=true"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}
	return db
}

次に、DBからFetchする関数を作成する。


var users []User

func fetchUsers(w http.ResponseWriter, r *http.Request) {
	db := dbInit()

	db.Find(&users)
	fmt.Println(users)
	profJson, _ := json.Marshal(users)
	fmt.Fprintf(w, string(profJson))
}

最後にエンドポイントにアクセスした際にfetchUsersを実行するように設定する。

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

func main() {
	handleRequests()
}

これでhttp://localhost:8081/usersにアクセスすると、

[{"ID":1,"CreatedAt":"2023-01-01T12:00:00Z","UpdatedAt":"2023-01-01T12:30:00Z","DeletedAt":null,"Name":"John Doe","Age":25,"IsActive":true},{"ID":2,"CreatedAt":"2023-01-02T09:15:00Z","UpdatedAt":"2023-01-02T10:00:00Z","DeletedAt":null,"Name":"Jane Smith","Age":30,"IsActive":false}]

が取得できた。

全体像はこんな感じ。

全体のコード

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"

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

type User struct {
	// gorm.Modelをつけると、idとCreatedAtとUpdatedAtとDeletedAtが作られる
	gorm.Model

	Name     string
	Age      int
	IsActive bool
}

var users []User

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

func main() {
	handleRequests()
}

func dbInit() *gorm.DB {
	dsn := "root:password@tcp(127.0.0.1:3306)/project?charset=utf8mb4&parseTime=true"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}
	return db
}

func fetchUsers(w http.ResponseWriter, r *http.Request) {
	db := dbInit()

	db.Find(&users)
	fmt.Println(users)
	profJson, _ := json.Marshal(users)
	fmt.Fprintf(w, string(profJson))
}

全体のコード(リファクタリング版)

ここまでをリファクタリングしてみる。

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/joho/godotenv"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type User struct {
	// gorm.Modelをつけると、idとCreatedAtとUpdatedAtとDeletedAtが作られる
	gorm.Model

	Name     string
	Age      int
	IsActive bool
}

var db *gorm.DB

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

func initDB() *gorm.DB {
	dsn := os.Getenv("DB_CONNECTION_STRING")
	if dsn == "" {
		log.Fatal("DB_CONNECTION_STRING 環境変数が設定されていません")
	}

	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatalf("データベースへの接続に失敗しました: %v", err)
	}

	return db
}

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

func main() {
	handleRequests()
}

func fetchUsers(w http.ResponseWriter, r *http.Request) {
	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))
}

.envを使用するために、

go get github.com/joho/godotenv

を実行する必要がある。