# Go LangでWebAPIを作成するために、GolangでエンドポイントにアクセスしDBからデータを取得する

Table of Contents
  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

を実行する必要がある。

My avatar

Thanks for reading my blog post! Feel free to check out my other posts or contact me via the social links in the footer.


More Posts

Comments