Tutorial Restful API Golang #4 : Insert Data ke Dalam Database


Tutorial Restful API Golang #4 : Insert Data ke Dalam Database

Halo teman-teman semuanya, pada artikel sebelumnya kita telah belajar bagaimana cara menampilkan list data dari database dalam format JSON di Go dan pada artikel kali ini, kita semua akan belajar bagaimana cara membuat proses insert data ke dalam database dan kita juga akan menerapkan validasi untuk data yang akan disimpan.

Langkah 1 - Menambahkan Function StorePost di Controller

Sekarang kita akan menambahkan function baru di dalam controller, silahkan teman-teman buka file controllers/postsController.go, kemudian ubah 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,
	})
}

Dari perubahan kode di atas, pertama kita import beberapa library, yaitu:

  1. errors
  2. net/http
  3. github.com/go-playground/validator/v10
import (
	"errors"
	"net/http"
	"santrikoding/backend-api/models"

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

Kemudian kita membuat struct dengan nama ValidatePostInput, di dalamnya kita memiliki 2 property, yaitu Title dan Content.

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

Di atas, masing-masing memiliki tag json untuk menentukan nama field saat di-serialize ke JSON, dan tag binding yang menandakan bahwa kedua field tersebut harus diisi (required) ketika melakukan binding data.

Selanjutnya, kita membuat struct lagi dengan nama ErrorMsg, struct ini nantinya akan digunakan untuk menyimpan pesan error yang akan dikirimkan sebagai respons JSON ketika terjadi kesalahan validasi.

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

Berikutnya, kita membuat function baru dengan nama GetErrorMsg, fungsi ini digunakan untuk mendapatkan pesan error berdasarkan jenis error yang terjadi. Pada contoh kode di atas, fungsi ini hanya menghandle satu jenis error yaitu "required". Jika sebuah field tidak diisi (required), maka fungsi ini akan mengembalikan pesan "This field is required". Jika jenis error tidak dikenali (misalnya, terjadi error selain "required"), maka akan dikembalikan pesan "Unknown error".

Dan terakhir, kita membuat function untuk proses insert data post ke dalam database, nama function tersebut adalah StorePost.

// store a post
func StorePost(c *gin.Context) {

	//...
	
}

Di dalam fungsi di atas, pertama kita membuat variable baru dengan nama input dan berisi struct yang sudah kita buat sebelumnya, yaitu ValidatePostInput.

//validate input
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

Kemudian, jika data yang dikirimkan sudah sesuai dengan validasi, maka kita akan mendeklarasikan variabel bernama post dengan tipe data models.Post. Variabel ini akan menampung data post baru yang akan disimpan.

//create post
post := models.Post{
    Title:   input.Title,
    Content: input.Content,
}

Setelah itu, kita lakukan proses insert data ke dalam database menggunakan method Create dari Gorm.

models.DB.Create(&post)

Terakhir, kita tinggal mengembalikan response dalam format JSON dengan status code 201 dan berisi informasi tentang keberhasilan proses insert data post ke dalam database.

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

Langkah 2 - Membuat Route API Store Post

Setelah berhasil menambahkan fungsi di dalam controller, maka langkah berikutnya adalah membuat route-nya.

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)

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

Dari perubahan kode di atas, kita membuat route baru dengan method POST dan path yang digunakan adalah /api/posts.

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

Langkah 3 - Uji Coba Rest API Store 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 dan untuk method-nya silahkan pilih POST.

Kemudian masuk di tab Body dan pilih raw dan masukkan JSON berikut ini.

{
    "title": "",
    "content": ""
}

Di atas, kita akan coba untuk mengosongkan nilai title dan body terlebih dahulu. Jika sudah, silahkan klik Send, jika berhasil maka kita akan mendapatkan response validasi yang berisi informasi data validasi yang dibutuhkan.

{
    "errors": [
        {
            "field": "Title",
            "message": "This field is required"
        },
        {
            "field": "Content",
            "message": "This field is required"
        }
    ]
}

Sekarang, silahkan ubah menjadi seperti berikut ini.

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

Jika sudah, silahkan klik Send, maka kita akan mendapatkan response success insert data ke dalam database.

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

Kesimpulan

Pada artikel ini, kita semua telah belajar bagaimana cara membuat validasi, insert data post ke dalam database dengan Rest API di GO.

Pada artikel berikutnya, kita semua akan belajar bagaimana cara menampilkan detail data berdasarkan ID di dalam Go 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