こんにちは、KOUKIです。
GolangのWebフレームワークであるfiberを使ってAPIを開発しています。
前回は、ModelのEmbeddedとProductデータの作成プログラムを実装しました。
今回は、UserとProductsモデルを関連付ける(LINK)テーブルモデル/APIを実装します。
尚、Udemyの「React, NextJS and Golang: A Rapid Guide – Advanced」コースを参考にしています。解釈は私が勝手に付けているので、本物をみたい場合は受講をお勧めします!
<目次>
前回
事前準備
フォルダ/ファイル作成
1 2 |
touch src/models/link.go touch src/controllers/linkController.go |
作るもの
Admin機能を作りたいと思います。エンドポイントは、次の通りです。
- GET/POST /api/admin/products
- GET/PUT/DELETE /api/admin/products/{product_id}
- GET /api/admin/users/{user_id}/links
- GET /api/admin/orders
- GET /api/admin/ambassadors
今回は、「/api/admin/users/{user_id}/links」への処理を実装します。
Linkモデル
DB操作のためのORMとして、GORMを使っています。これを使うと、Goの構造体からデータベースのスキーマーを簡単に作成したり、クエリを書かなくてもデータの作成・取得・更新・削除処理の実装が容易になるので、おすすめです。
Modelの追加
GORMのfierignKeyとmany2manyを使って、UserとProductをLinkさせる構造体を実装します。
1 2 3 4 5 6 7 8 9 10 |
// link.go package models type Link struct { Model Code string `json:"code"` UserID uint `json:"user_id"` User User `json:"user" gorm:"foreignKey:UserID"` Products []Product `json:"products" gorm:"many2many:link_products"` } |
fierignKeyでは、UserのIDを紐づけてます。そして、many2manyでは、LinkとProductsを紐付けました。
「link_products」は、product「s」と複数形になっていますが、これはGORMのデフォルトの挙動で、Product構造体から「Products(複数形)」が作成されるので、このように指定しています。
マイグレーションの追加
LinkもGORMのマイグレーションに追加します。
1 2 3 4 5 6 |
// database/db.go ... func AutoMigrate() { // User構造体に沿ってテーブルのスキーマーを作成する DB.AutoMigrate(models.User{}, models.Product{}, models.Link{}) } |
AutoMigrageメソッドにLinkモデルを追加するだけで、dockerコンテナ立ち上げ時に、自動的にスキーマーを作ってくれます。



Link API
続いて、Link APIの実装を進めていきます。
ルートの追加
「/api/admin/users/{user_id}/links」へのルートを実装します。
1 2 3 4 5 6 7 8 |
// routes/routes.go ... func Setup(app *fiber.App) { ... // Middleware ... adminAuthenticated.Get("users/:id/links", controllers.Link) } |
コントローラーの追加
Linkコントローラーを実装しましょう。
user idに紐づくLink情報を取得します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// linkController.go package controllers import ( "admin/src/database" "admin/src/models" "strconv" "github.com/gofiber/fiber/v2" ) func Link(ctx *fiber.Ctx) error { id, _ := strconv.Atoi(ctx.Params("id")) var links []models.Link database.DB.Where("user_id = ?", id).Find(&links) return ctx.JSON(links) } |
検証
以下のパラメータで、動作検証をしましょう。
- URL: http://localhost:8000/api/admin/users/3/links
- 形式: GET

エラーは発生しないようですね。該当データがないので、戻り値は空でOKです。
次回
次回は、Order APIを実装しましょう。
Go言語まとめ
ソースコード
ここまでのソースコードを以下に記載します。
link.go
1 2 3 4 5 6 7 8 9 10 |
// link.go package models type Link struct { Model Code string `json:"code"` UserID uint `json:"user_id"` User User `json:"user" gorm:"foreignKey:UserID"` Products []Product `json:"products" gorm:"many2many:link_products"` } |
db.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// database/db.go package database import ( "admin/src/models" "gorm.io/driver/mysql" "gorm.io/gorm" ) const ( // ユーザー:パスワード@tcp(dockerのサービス名(db):port)/db名 dsn = "admin:admin@tcp(db:3306)/ambassador?charset=utf8mb4&parseTime=True&loc=Local" ) var DB *gorm.DB func Connect() { var err error DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic("Could not connect with the database!") } } func AutoMigrate() { // User構造体に沿ってテーブルのスキーマーを作成する DB.AutoMigrate(models.User{}, models.Product{}, models.Link{}) } |
routes.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// routes/routes.go package routes import ( "admin/src/controllers" "admin/src/middleware" "github.com/gofiber/fiber/v2" ) func Setup(app *fiber.App) { // GROUP api := app.Group("api") admin := api.Group("admin") // No Middleware admin.Post("register", controllers.Register) admin.Post("login", controllers.Login) // Middleware adminAuthenticated := admin.Use(middleware.IsAuthenticate) adminAuthenticated.Get("user", controllers.User) adminAuthenticated.Post("logout", controllers.Logout) adminAuthenticated.Put("info", controllers.UpdateInfo) adminAuthenticated.Put("password", controllers.UpdatePassword) adminAuthenticated.Get("ambassadors", controllers.Ambassadors) adminAuthenticated.Get("products", controllers.Products) adminAuthenticated.Post("products", controllers.CreateProducts) adminAuthenticated.Get("products/:id", controllers.GetProduct) adminAuthenticated.Put("products/:id", controllers.UpdateProduct) adminAuthenticated.Delete("products/:id", controllers.DeleteProduct) adminAuthenticated.Get("users/:id/links", controllers.Link) } |
linkController.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// linkController.go package controllers import ( "admin/src/database" "admin/src/models" "strconv" "github.com/gofiber/fiber/v2" ) func Link(ctx *fiber.Ctx) error { id, _ := strconv.Atoi(ctx.Params("id")) var links []models.Link database.DB.Where("user_id = ?", id).Find(&links) return ctx.JSON(links) } |
コメントを残す
コメントを投稿するにはログインしてください。