昨天體驗使用 Gin 來撰寫第一支 Web Backend API
今天要來整合先前寫的 SQL 資料庫,透過呼叫 API,來與 SQL 資料庫進行互動
目前我們已經寫好了 repository 裡的 album.go
以及目前我們跟 repository 的互動都寫在 main.go 裡面,現在我們要來將其移到對應的 Handler Function 內
我們透過定義一個 private 的 param struct 以及使用 Gin 提供的 BindJSON 來解析 HTTP Body 傳進來的 JSON Object 作為 data 變數
並使用 data 內的值當作我們新增到 Album 內各欄位的值
如果有發生錯誤,則以 JSON 回傳錯誤訊息,反之,則以 JSON 回傳新增成功訊息
func Create(c *gin.Context) {
    type param struct {
        Title       string `json:"title"`
        Artist      string `json:"artist"`
        ReleaseDate string `json:"releaseDate"`
    }
    var data param
    err := c.BindJSON(&data)
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Create Failed" + err.Error(),
        })
        return
    }
    album := database.Album{
        ID:          uuid.New().String(),
        Title:       data.Title,
        Artist:      data.Artist,
        ReleaseDate: data.ReleaseDate,
    }
    err = repository.Create(album)
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Create Failed,Error:" + err.Error(),
        })
        return
    }
    c.JSON(http.StatusOK, gin.H{
        "message": "Create Success",
    })
}

▲ Postman 測試結果
我們透過使用 Gin 提供的 Query 來取得網址上的 Query 參數值,並作為變數 albumId
並使用 albumId 來向 SQL 資料庫進行篩選符合的值
如果有發生錯誤,則以 JSON 回傳錯誤訊息,反之,則以 JSON 回傳讀取成功訊息
func Get(c *gin.Context) {
    albumId := c.Query("id")    
    
    result, err := repository.Read(albumId)
    if errors.Is(err, gorm.ErrRecordNotFound) {
        c.JSON(http.StatusOK, gin.H{
            "message": "Get Success,No record found",
    	})
        return
    } else if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Get Failed,Error:" + err.Error(),
        })
        return
    }    
    
    c.JSON(http.StatusOK, gin.H{
        "message": "Get Success",
        "albums":  result,
    })
}

▲ Postman 測試結果
func GetAll(c *gin.Context) {
    result, err := repository.ReadAll()
    if errors.Is(err, gorm.ErrRecordNotFound) {
        c.JSON(http.StatusOK, gin.H{
            "message": "Get Success,No record found",
        })
        return
    } else if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Get Failed,Error:" + err.Error(),
        })
        return
    }    
    
    c.JSON(http.StatusOK, gin.H{
        "message": "Get Success",
        "albums":  result,
    })
}

▲ Postman 測試結果
我們透過定義一個 private 的 param struct 以及使用 Gin 提供的 BindJSON 來解析 HTTP Body 傳進來的 JSON Object 作為 data 變數
並使用 data 內的值當作我們更新 Album 內各欄位的值 (除 id 欄位)
如果有發生錯誤,則以 JSON 回傳錯誤訊息,反之,則以 JSON 回傳更新成功訊息
func Update(c *gin.Context) {
    type param struct {
        ID          string `json:"id"`
        Title       string `json:"title"`
        Artist      string `json:"artist"`
        ReleaseDate string `json:"releaseDate"`
    }
    var data param
    err := c.BindJSON(&data)
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Update Failed,Error:" + err.Error(),
        })
        return
    }    
    
    result, err := repository.Read(data.ID)
    if errors.Is(err, gorm.ErrRecordNotFound) {
        c.JSON(http.StatusOK, gin.H{
            "message": "Update Success,No record found",
        })
        return
    } else if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Update Failed,Error:" + err.Error(),
        })
        return
    }    
    
    repository.Update(result, database.Album{
        Title:       data.Title,
        Artist:      data.Artist,
        ReleaseDate: data.ReleaseDate,
    })   
    
    c.JSON(http.StatusOK, gin.H{
        "message": "Update Success",
    })
}

▲ Postman 測試結果
我們透過定義一個 private 的 param struct 以及使用 Gin 提供的 BindJSON 來解析 HTTP Body 傳進來的 JSON Object 作為 data 變數
並使用 data 內的值 (id) 當作我們從 SQL 資料庫篩選的值
如果有發生錯誤,則以 JSON 回傳錯誤訊息,反之,則以 JSON 回傳刪除成功訊息
func Delete(c *gin.Context) {
    type param struct {
        ID string `json:"id"`
    }
    var data param
    err := c.BindJSON(&data)
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Delete Failed,Error:" + err.Error(),
        })
        return
    }    
    
    repository.Delete(data.ID)    
    
    c.JSON(http.StatusOK, gin.H{
        "message": "Delete Success",
    })
}

▲ Postman 測試結果
func DeleteAll(c *gin.Context) {
    err := repository.DeleteAll()
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Delete All Failed,Error:" + err.Error(),
        })
        return
    }    
    
    c.JSON(http.StatusOK, gin.H{
        "message": "Delete All Success",
    })
}

▲ Postman 測試結果
今天我們將先前寫的 SQL 資料庫進行整合
接下來就要開始進到跟本次參賽主題 Cloud Native 相關的內容了
明天要來我們寫好的 Backend API 包成多架構的 Docker Image,方便後面我們部署到 Kubernetes 上
那麼就明天見啦~