で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))
}
handleRequests
をmain
関数の中で実行すれば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
を実行する必要がある。