前回は、バリデーションとDAOについて実装を行いました。本日は、GORMを使ったMySQLのデータ操作を行なっていきたいと思います。
前回
プロジェクト構成
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 |
api ├── README.md ├── app │ ├── application.go │ └── url_mappings.go ├── controllers │ ├── ping_controller.go │ └── products │ ├── products_controller.go │ └── products_controller_test.go ├── datasources │ └── mysql │ └── products_db │ └── products_db.go ├── domain │ └── products │ ├── product_dao.go │ ├── product_dao_test.go │ ├── product_dto.go │ └── product_test.go ├── main.go ├── services │ └── products_service.go └── utils └── errors └── api_errors.go</code></pre></div> |
GORMによるProductの登録
まずは、Productの保存処理を実装します。
Internal Server Errorの追加
DB操作時に発生するエラーを定義しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// api_errors.go package errors import "net/http" type ApiErr struct { Message string `json:"message"` Status int `json:"status"` Error string `json:"error"` } ... func NewInternalServerError(message string) *ApiErr { return &ApiErr{ Message: message, Status: http.StatusInternalServerError, Error: "internal_server_error", } } |
NewInternalServerErrorでは、HTTPステータスコード500番を発生させます。
DB操作時の致命的なエラーは、この例外を通して発生させましょう。
GORM – 登録処理の実装
続いて、データを登録する処理を書きましょう。
以前実装したSaveメソッドを書き換えます。
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 |
// product_dao.go package products import ( "fmt" "log" "github.com/gouser/money-boy/api/datasources/mysql/products_db" "github.com/gouser/money-boy/api/utils/errors" ) ... // Save - product func (p *Product) Save() *errors.ApiErr { // https://gorm.io/ja_JP/docs/error_handling.html if result := products_db.Client.Create(&p); result.Error != nil { return errors.NewInternalServerError( fmt.Sprintf("error when trying to save product: %s", result.GetErrors()), ) } return nil } |
GORMによるマイグレーションについて(余談です)
マイグレーションとは、指定したDBのスキーマーを自動生成してくれる便利な機能です。
GORMには、マイグレーション機能が実装されています。
しかし、環境構築編でDBのスキーマーを自動生成できるようにしてあるので、今回はマイグレーション処理を割愛したいと思います。
動作確認
dockerコンテナを立ち上げて、動作確認をしてみましょう。
1 |
docker-compose up |
Talend API Testerからリクエストを送ってみます。
1 2 3 4 5 6 |
POST: http://localhost:8080/products { "name": "coca cola", "detail": "The coca cola is very very delicious drink", "price": 200 } |

200OKが返されました。
ブラウザから「localhost:8888」にアクセスして、phpmyadminページを開いてみましょう。

問題なくレコードが登録されているようです。
この少しずつ開発が進んでいく感じがいいですね。
また、商品のnameは、UNIQUE KEYを設定しているので、同じ商品名は入力できないようになっています。

テストについて
今まではテストを書いてきましたが、一旦後回しにして先に進みますね^^
MySQLコンテナと絡ませるテストコードの書き方を模索中です。
GORMによるプロダクトの検索
今度は、Productの検索処理を実装しましょう。
GORM – 検索処理の実装
product_dao.goファイルのGetメソッドを書き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// product_dao.go package products import ( "fmt" "github.com/gouser/money-boy/api/datasources/mysql/products_db" "github.com/gouser/money-boy/api/utils/errors" ) // Get - product func (p *Product) Get() *errors.ApiErr { if result := products_db.Client.Where("id = ?", p.Model.ID).Find(&p); result.Error != nil { return errors.NewInternalServerError( fmt.Sprintf("error when trying to get product: %s", result.GetErrors()), ) } return nil } |
GORMを使うとコード量が少なく済むのでいい感じですね。
Whereメソッドにて、idをキーにデータを検索するように実装しました。Findは検索結果から得られた情報を全て取得するメソッドですが、idはユニークキーなので、通常は1つしかデータを取らないはずです。
その他のQueryの一覧は、こちらを確認ください。
動作確認
以下のコマンドで、dockerコンテナを起動してください。
1 |
docker-compose up |
Talend API Testerで存在するProduct IDをつけてリクエストを送ってみましょう。
「http://localhost:8080/products/1」

問題なく取得できたようですね。
次は、存在しないIDを送ってみましょう。
「http://localhost:8080/products/1000000」

期待通りにエラーが発生しました。
次回
次回は、MySQLのエラーハンドリングについて学びましょう。
コメントを残す
コメントを投稿するにはログインしてください。