前回は、Go言語にてMySQLの更新処理を実装しました。
今回は、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 27 28 29 |
tree api 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 └── mysqlutils └── mysql_utils.go |
削除処理の実装
さっそく、削除処理を実装していきましょう。
URLマッピングの追加
最初に、リクエスト先を追加します。
app配下のurl_mappings.goに以下を追加してください。
1 2 3 4 5 6 7 8 9 10 11 |
// app/url_mappings.go package app import "github.com/gouser/money-boy/api/controllers/products" func mapUrls() { ... router.DELETE("/products/:product_id", products.DeleteProduct) } |
DELETEメソッドで「products/<product id>」にリクエストするとDeleteProductが実行されるように実装しました。
コントローラーの追加
続いて、controllers/products配下のproducts_controller.goにDeleteProduct関数を実装します。
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 34 35 36 37 |
// controller/products/products_controller.go package products import ( "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/gouser/money-boy/api/domain/products" "github.com/gouser/money-boy/api/services" "github.com/gouser/money-boy/api/utils/errors" ) // productIDの取得を外に出した func getProductID(productIDParam string) (uint, *errors.ApiErr) { productID, productErr := strconv.ParseUint(productIDParam, 10, 64) if productErr != nil { return 0, errors.NewBadRequestError("product id should be a number") } return uint(productID), nil } // DeleteProduct - Delete product func DeleteProduct(c *gin.Context) { productID, idErr := getProductID(c.Param("product_id")) if idErr != nil { c.JSON(idErr.Status, idErr) return } if err := services.DeleteProduct(productID); err != nil { c.JSON(err.Status, err) return } c.JSON(http.StatusOK, map[string]string{"status": "deleted"}) } |
GetやUpdateと同様にリクエストからproduct idを取得後、DeleteProductサービスに処理を振り分けています。
getProductIDは、IDを取得するためのメソッドで、GetやUpdate関数と重複している処理を切り出したものです。
GetやUpdateも書き換えましょう。
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 34 35 36 37 38 39 40 41 42 43 44 |
// UpdateProduct - Update product func UpdateProduct(c *gin.Context) { productID, idErr := getProductID(c.Param("product_id")) if idErr != nil { c.JSON(idErr.Status, idErr) return } var product products.Product if err := c.ShouldBindJSON(&product); err != nil { apiErr := errors.NewBadRequestError("invalid json body") c.JSON(apiErr.Status, apiErr) return } product.ID = productID isPartial := c.Request.Method == http.MethodPatch result, err := services.UpdateProduct(isPartial, product) if err != nil { c.JSON(err.Status, err) return } c.JSON(http.StatusOK, result) } ... // GetProduct - Get product by product id func GetProduct(c *gin.Context) { productID, idErr := getProductID(c.Param("product_id")) if idErr != nil { c.JSON(idErr.Status, idErr) return } product, getErr := services.GetProduct(productID) if getErr != nil { c.JSON(getErr.Status, getErr) return } c.JSON(http.StatusOK, product) } |
サービスの追加
続いて、サービスを追加しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// products_service.go package services import ( "github.com/jinzhu/gorm" "github.com/gouser/money-boy/api/domain/products" "github.com/gouser/money-boy/api/utils/errors" ) // DeleteProduct - Service func DeleteProduct(productID uint) *errors.ApiErr { product := &products.Product{Model: gorm.Model{ID: productID}} return product.Delete() } |
Deleteの追加
公式サイトを参考に、Deleteメソッドを追加します。
domain/products/product_dao.goを開いてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// domain/products/product_dao.go package products import ( "github.com/gouser/money-boy/api/datasources/mysql/products_db" "github.com/gouser/money-boy/api/utils/errors" "github.com/gouser/money-boy/api/utils/mysqlutils" ) // Delete - product func (p *Product) Delete() *errors.ApiErr { if result := products_db.Client.Delete(&p); result.Error != nil { return mysqlutils.ParseError(result.Error) } return nil } |
今回は、物理削除(データベースからの削除)ではなく、論理削除を選択しました。論理削除では、データベースからデータは消えませんが、DeletedAtに削除日時が追加されます。
動作確認
動作確認のため、dockerコンテナを起動しましょう。
1 |
docker-compose up |
最初に「http://localhost:8080/products/1」にアクセスして、データを確認します。この時「Get」メソッドを使用します。
Talend API Testerを開いて、Sendボタンを押下しましょう。

1 2 3 4 5 6 7 8 9 10 11 |
// ID = 1のデータ { "ID": 1, "CreatedAt": "2020-05-23T23:56:23Z", "UpdatedAt": "2020-05-29T20:35:16Z", "DeletedAt": null, "name": "PATCH TEST", "detail": "Update Other Somthing Drink", "price": 500, "img": null } |
では、Deleteメソッドに切り替えて、リクエストを送信してみましょう。

Deleteステータスが返却されました。
1 2 3 |
{ "status": "deleted" } |
もう一度、Getメソッドを使用します。

404エラーが返却されました。
phpmyadmin(localhost:8888)にアクセスしてみましょう。

deleted_atに日付が追加されているレコードがありますが、これが先ほど論理削除したデータになります。
問題なく機能しているようですね。
おわりに
これで一通り、Create, Read, Update, Delete処理を実装できましたので、一旦終わりにします。
次は、フロントエンド部分をReactで作っていく予定です!!
それでは、また!
コメントを残す
コメントを投稿するにはログインしてください。