Tutorial Restful API Golang #6 : Update Data ke Dalam Database


Tutorial Restful API Golang #6 : Update Data ke Dalam Database

Halo teman-teman semuanya, pada artikel sebelumnya kita telah belajar bagaimana cara menampilkan detail data post berdasarkan ID di Go dan pada kesempatan kali ini kita semua akan belajar bagaimana cara membuat proses update data ke dalam database di Go.

Langkah 1 - Menambahkan Function UpdatePost di Controller

Sekarang, silahkan teman-teman buka file controllers/postsController.go, kemudian ubah semua kode-nya menjadi seperti berikut ini.

controllers/postController.go

package controllers

import (
	"errors"
	"net/http"
	"santrikoding/backend-api/models"

	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
)

// type validation post input
type ValidatePostInput struct {
	Title   string `json:"title" binding:"required"`
	Content string `json:"content" binding:"required"`
}

// type error message
type ErrorMsg struct {
	Field   string `json:"field"`
	Message string `json:"message"`
}

// function get error message
func GetErrorMsg(fe validator.FieldError) string {
	switch fe.Tag() {
	case "required":
		return "This field is required"
	}
	return "Unknown error"
}

// get all posts
func FindPosts(c *gin.Context) {

	//get data from database using model
	var posts []models.Post
	models.DB.Find(&posts)

	//return json
	c.JSON(200, gin.H{
		"success": true,
		"message": "Lists Data Posts",
		"data":    posts,
	})
}

// store a post
func StorePost(c *gin.Context) {
	//validate input
	var input ValidatePostInput
	if err := c.ShouldBindJSON(&input); err != nil {
		var ve validator.ValidationErrors
		if errors.As(err, &ve) {
			out := make([]ErrorMsg, len(ve))
			for i, fe := range ve {
				out[i] = ErrorMsg{fe.Field(), GetErrorMsg(fe)}
			}
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errors": out})
		}
		return
	}

	//create post
	post := models.Post{
		Title:   input.Title,
		Content: input.Content,
	}
	models.DB.Create(&post)

	//return response json
	c.JSON(201, gin.H{
		"success": true,
		"message": "Post Created Successfully",
		"data":    post,
	})
}

// get post by id
func FindPostById(c *gin.Context) {
	var post models.Post
	if err := models.DB.Where("id = ?", c.Param("id")).First(&post).Error; err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
		return
	}

	c.JSON(200, gin.H{
		"success": true,
		"message": "Detail Data Post By ID : " + c.Param("id"),
		"data":    post,
	})
}

// update post
func UpdatePost(c *gin.Context) {
	var post models.Post
	if err := models.DB.Where("id = ?", c.Param("id")).First(&post).Error; err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
		return
	}

	//validate input
	var input ValidatePostInput
	if err := c.ShouldBindJSON(&input); err != nil {
		var ve validator.ValidationErrors
		if errors.As(err, &ve) {
			out := make([]ErrorMsg, len(ve))
			for i, fe := range ve {
				out[i] = ErrorMsg{fe.Field(), GetErrorMsg(fe)}
			}
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errors": out})
		}
		return
	}

	//update post
	models.DB.Model(&post).Updates(input)

	c.JSON(200, gin.H{
		"success": true,
		"message": "Post Updated Successfully",
		"data":    post,
	})
}

Dari perubahan kode di atas, kita menambahkan function baru dengan nama UpdatePost.

// update post
func UpdatePost(c *gin.Context) {

	//...
	
}

Kemudian kita membuat kondisi yang mirip dengan fungsi FindPostById sebelumnya. Ini melakukan pencarian terhadap posting berdasarkan ID yang diambil dari parameter context c.Param("id").

if err := models.DB.Where("id = ?", c.Param("id")).First(&post).Error; err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
        return
}

Setelah itu, kita mendeklarasikan variabel input dengan tipe data ValidatePostInput. Variabel ini akan digunakan untuk menyimpan data input yang dikirim client untuk update post.

var input ValidatePostInput

Kemudian kita membuat kondisi untuk proses validasi input.

if err := c.ShouldBindJSON(&input); err != nil {

	//...

}

Di atas digunakan untuk melakukan binding data dari request body ke struktur ValidatePostInput. Jika terjadi error saat binding (err != nil), maka kita akan menampilkan error validasi.

var ve validator.ValidationErrors
if errors.As(err, &ve) {
    out := make([]ErrorMsg, len(ve))
    for i, fe := range ve {
        out[i] = ErrorMsg{fe.Field(), getErrorMsg(fe)}
    }
    c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errors": out})
}
return

Jika data yang dikirimkan oleh client sudah sesuai dengan validasi di atas, maka kita akan melakukan proses update data ke dalam database menggunakan models.

//update post
models.DB.Model(&post).Updates(input)

Dan terakhir, kita tinggal mengembalikan response dalam format JSON yang berisi informasi data post yang berhasil diupdate.

c.JSON(200, gin.H{
        "success": true,
        "message": "Post Updated Successfully",
        "data":    post,
})

Langkah 2 - Membuat Route API Update Post

Sekarang, kita lanjutkan untuk membuat route untuk proses update data post, jadi silahkan teman-teman buka file main.go, kemudian ubah kode-nya menjadi seperti berikut ini.

main.go

package main

import (
	"santrikoding/backend-api/controllers"
	"santrikoding/backend-api/models"

	"github.com/gin-gonic/gin"
)

func main() {
	//inisialiasai Gin
	router := gin.Default()

	//panggil koneksi database
	models.ConnectDatabase()

	//membuat route dengan method GET
	router.GET("/", func(c *gin.Context) {

		//return response JSON
		c.JSON(200, gin.H{
			"message": "Hello World!",
		})
	})

	//membuat route get all posts
	router.GET("/api/posts", controllers.FindPosts)

	//membuat route store post
	router.POST("/api/posts", controllers.StorePost)

	//membuat route detail post
	router.GET("/api/posts/:id", controllers.FindPostById)

	//membuat route update post
	router.PUT("/api/posts/:id", controllers.UpdatePost)

	//mulai server dengan port 3000
	router.Run(":3000")
}

Dari perubahan kode di atas, kita menambahkan route baru dengan method PUT dan path yang digunakan adalah /api/posts/:id.

//membuat route update post
router.PUT("/api/posts/:id", controllers.UpdatePost)

Langkah 3 - Uji Coba Rest API Update Post

Silahkan restrat server Go-nya terlebih dahulu, yaitu dengan cara distop dan start lagi.

Silahkan teman-teman buka aplikasi Postman, kemudian masukkan URL berikut ini http://localhost:3000/api/posts/1 dan untuk method-nya silahkan pilih PUT.

Di atas, kita berikan contoh melakukan get data dengan ID 1

Setelah itu, buka tab Body dan pilih raw dan masukkan JSON berikut ini.

{
    "title": "Belajar Restful API Golang - Edit",
    "content": "Di SantriKoding - Edit"
}

Di atas, kita tambahkan -Edit di dalam value-nya. Dan jika sudah silahkan teman-teman klik Send dan jika berhasil maka akan mendapatkan response JSON seperti berikut ini.

{
    "data": {
        "id": 1,
        "title": "Belajar Restful API Golang - Edit",
        "content": "Di SantriKoding - Edit"
    },
    "message": "Post Updated Successfully",
    "success": true
}

Kesimpulan

Pada artikel ini, kita semua telah belajar bagaimana cara melakukan proses update data ke dalam database dengan Rest API di Go.

Pada artikel berikutnya, kita semua akan belajar bagaimana cara membuat proses delete data dari database di Go dengan Rest API.

Terima Kasih



Fika Ridaul Maulayya
Full-Stack Developer, Content Creator and CO-Founder SantriKoding.com

Suka dengan tulisan di SantriKoding? Kamu bisa memberikan dukungan dengan berdonasi atau bagikan konten ini di sosial media. Terima kasih atas dukungan Anda!

KEBIJAKAN KOMENTAR

Saat memberikan komenatar silahkan memberikan informasi lengkap tentang error, seperti: screenshot, link kode, dll. Baca aturan komentar kami