Membuat validasi dengan validator di Gofiber

Langkah-langkah untuk menambahkan validasi menggunakan github.com/go-playground/validator/v10 adalah sebagai berikut:

  1. Instalasi Library Validator: Pastikan Anda telah menginstal library github.com/go-playground/validator/v10 dengan menggunakan perintah:

    go get -u github.com/go-playground/validator/v10
  2. Membuat File Validation Helper: Buat file validation.go di dalam folder helpers dan tambahkan fungsi-fungsi validasi yang diperlukan.

  3. Mengubah Struktur Model: Tambahkan tag validate pada bidang model yang perlu divalidasi.

  4. Mengubah Kontroler: Di dalam kontroler, gunakan fungsi validasi dari helper yang telah dibuat untuk memvalidasi input sebelum melakukan operasi CRUD.

Berikut adalah full code untuk implementasi langkah-langkah di atas:

src/helpers/validation.go

package helpers

import (
	"github.com/go-playground/validator/v10"
)

var validate = validator.New()

type ErrorResponse struct {
	FailedField string `json:"failed_field"`
	Tag         string `json:"tag"`
	Value       string `json:"value"`
}

func ValidateStruct(param any) []*ErrorResponse {
	var errors []*ErrorResponse
	validate := validator.New()
	err := validate.Struct(param)
	if err != nil {
		for _, err := range err.(validator.ValidationErrors) {
			element := ErrorResponse{
				FailedField: err.StructNamespace(),
				Tag:         err.Tag(),
				Value:       err.Param(),
			}
			errors = append(errors, &element)
		}
	}
	return errors
}

src/models/Category.go

package models

import (
	"gofiber/src/configs"

	"gorm.io/gorm"
)

type Category struct {
	gorm.Model
	Name     string    `json:"name" validate:"required,min=3,max=50"`
	URLImage string    `json:"url_image"`
	Products [] ApiProduct `json:"products"`
}

src/controllers/CategoryControllers.go

package controllers

import (
	"fmt"
	"strconv"

	"github.com/gofiber/fiber/v2"
	"gofiber/src/helpers"
	"gofiber/src/models"
)

func CreateCategory(c *fiber.Ctx) error {
	var category models.Category
	if err := c.BodyParser(&category); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"error": "Failed to parse request body",
		})
	}

	errors := helpers.ValidateStruct(category)
	if len(errors) > 0 {
		return c.Status(fiber.StatusUnprocessableEntity).JSON(errors)
	}

	models.PostCategory(&category)

	return c.Status(fiber.StatusCreated).JSON(fiber.Map{
		"message": "Category created successfully",
	})
}

func UpdateCategory(c *fiber.Ctx) error {
	id, _ := strconv.Atoi(c.Params("id"))

	var updatedCategory models.Category
	if err := c.BodyParser(&updatedCategory); err != nil {
		c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"message": "Invalid request body",
		})
		return err
	}

	errors := helpers.ValidateStruct(updatedCategory)

	if len(errors) > 0 {
		return c.Status(fiber.StatusUnprocessableEntity).JSON(errors)
	}

	models.UpdateCategory(id, &updatedCategory)

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"message": "Category updated successfully",
	})
}

src/models/Products.go

import (
	"gofiber/src/configs"

	"gorm.io/gorm"
)

type Product struct {
	gorm.Model
	Name       string  `json:"name" validate:"required,min=3,max=100"`
	Price      float64 `json:"price" validate:"required,min=0"`
	Stock      int     `json:"stock" validate:"required,min=0"`
	CategoryID uint    `json:"category_id"` 
	Category   Category `gorm:"foreignKey:CategoryID"`
}

src/controllers/ProductControllers.go

package controllers

import (
	"fmt"
	"strconv"

	"github.com/gofiber/fiber/v2"
	"gofiber/src/helpers"
	"gofiber/src/models"
)

func CreateProduct(c *fiber.Ctx) error {
	var newProduct models.Product
	if err := c.BodyParser(&newProduct); err != nil {
		c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"message": "Invalid request body",
		})
		return err
	}

	errors := helpers.ValidateStruct(newProduct)
	if len(errors) > 0 {
		return c.Status(fiber.StatusUnprocessableEntity).JSON(errors)
	}
	models.PostProduct(&newProduct)
	return c.Status(fiber.StatusCreated).JSON(fiber.Map{
		"message": "Product created successfully",
	})
}

func UpdateProduct(c *fiber.Ctx) error {
	id, _ := strconv.Atoi(c.Params("id"))

	var updatedProduct models.Product
	if err := c.BodyParser(&updatedProduct); err != nil {
		c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"message": "Invalid request body",
		})
		return err
	}

	errors := helpers.ValidateStruct(updatedProduct)
	if len(errors) > 0 {
		return c.Status(fiber.StatusUnprocessableEntity).JSON(errors)
	}

	err := models.UpdateProduct(id, &updatedProduct)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
			"message": fmt.Sprintf("Failed to update product with ID %d", id),
		})
	}
	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"message": fmt.Sprintf("Product with ID %d updated successfully", id),
	})
}

Dengan langkah-langkah di atas, Anda telah menambahkan validasi menggunakan github.com/go-playground/validator/v10 untuk model dan controller Anda. Kini aplikasi Anda akan memvalidasi input sebelum melakukan operasi CRUD pada produk dan kategori.

sumber : Dokumentasi

Last updated