# Implementasi MVC di Gofiber

&#x20;berikut adalah struktur folder yang diinginkan beserta penjelasan singkat untuk setiap direktori:

```
project
│   
├── src
|   ├── controllers
|   |   └── ProductController.go
|   ├── models
|   |   └── Products.go
|   └── routes
|       └── main.go
└── main.go
```

1. **src**: Direktori utama yang berisi seluruh kode aplikasi.
   * **controllers**: Direktori untuk menyimpan file-file yang berisi logika aplikasi terkait dengan pengaturan dan manipulasi data.
   * **models**: Direktori untuk menyimpan definisi struktur data atau model yang digunakan dalam aplikasi.
   * **routes**: Direktori untuk menyimpan file-file yang berisi definisi route atau endpoint dari aplikasi.
2. **main.go**: File utama yang berfungsi sebagai entry point atau titik awal dari aplikasi. Biasanya digunakan untuk menginisialisasi server dan setup awal lainnya.

Berikut adalah langkah-langkahnya:

1. **Buat Struktur Folder**: Buat struktur folder sesuai dengan yang diminta, yaitu `controllers`, `models`, dan `routes`.
2. **Pindahkan Fungsi Logika ke Controllers**: Pindahkan fungsi-fungsi logika terkait dengan aplikasi, seperti inisialisasi produk, membuat produk baru, memperbarui produk, dan menghapus produk, ke dalam file `ProductController.go` di dalam folder `controllers`.
3. **Pindahkan Struct ke Models**: Pindahkan definisi struct `Product` ke dalam file `Products.go` di dalam folder `models`.
4. **Pindahkan Routing**: Pindahkan routing aplikasi dari file `main.go` ke dalam file `main.go` di dalam folder `routes`.
5. **Atur Import dan Ekspor**: Pastikan untuk mengimpor dan mengekspor fungsi dan struct yang diperlukan dengan benar.

Berikut adalah implementasinya:

#### models/Products.go

```go
package models

type Product struct {
	ID    int     `json:"id"`
	Name  string  `json:"name"`
	Price float64 `json:"price"`
	Stock int     `json:"stock"`
}
```

#### controllers/ProductController.go

```go
package controllers

import (
	"fmt"
	"gofiber/src/models"
	"strconv"

	"github.com/gofiber/fiber/v2"
)

var products = []models.Product{
	{ID: 1, Name: "Product A", Price: 10.99, Stock: 100},
	{ID: 2, Name: "Product B", Price: 20.50, Stock: 50},
	{ID: 3, Name: "Product C", Price: 15.75, Stock: 75},
}

func GetAllProducts(c *fiber.Ctx) error {

	// Kirim data produk dalam format JSON
	return c.JSON(products)
}

func GetProductById(c *fiber.Ctx) error {
	// Dapatkan ID produk dari parameter route
	paramId := c.Params("id")
	id, _ := strconv.Atoi(paramId)

	// Panggil fungsi initProducts untuk mendapatkan data produk
	// products := initProducts()

	// Temukan produk dengan ID yang sesuai
	var foundProduct models.Product
	for _, p := range products {
		if p.ID == id {
			foundProduct = p
			break
		}
	}

	// Kirim detail produk dalam format JSON
	return c.JSON(foundProduct)
}

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

	// Panggil fungsi initProducts untuk mendapatkan data produk
	// products := initProducts()

	// Generate ID untuk produk baru (misalnya, ID terakhir + 1)
	newProduct.ID = len(products) + 1

	// Tambahkan produk baru ke daftar produk
	products = append(products, newProduct)

	// Kirim respons
	return c.Status(fiber.StatusCreated).JSON(fiber.Map{
		"message": "Product created successfully",
		"product": newProduct,
	})
}

func UpdateProduct(c *fiber.Ctx) error {
	// Dapatkan ID produk dari parameter route
	id, _ := strconv.Atoi(c.Params("id"))

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

	// Temukan produk dengan ID yang sesuai
	var foundIndex int = -1
	for i, p := range products {
		if p.ID == id {
			foundIndex = i
			break
		}
	}

	// Jika produk ditemukan, perbarui produk
	if foundIndex != -1 {
		products[foundIndex] = updatedProduct
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"message": fmt.Sprintf("Product with ID %d updated successfully", id),
			"product": updatedProduct,
		})
	} else {
		return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
			"message": fmt.Sprintf("Product with ID %d not found", id),
		})
	}
}

func DeleteProduct(c *fiber.Ctx) error {
	// Dapatkan ID produk dari parameter route
	id, _ := strconv.Atoi(c.Params("id"))

	// Temukan indeks produk yang akan dihapus
	var foundIndex int = -1
	for i, p := range products {
		if p.ID == id {
			foundIndex = i
			break
		}
	}

	// Jika produk ditemukan, hapus produk
	if foundIndex != -1 {
		// Hapus produk dari slice menggunakan teknik slice trick
		products = append(products[:foundIndex], products[foundIndex+1:]...)
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"message": fmt.Sprintf("Product with ID %d deleted successfully", id),
		})
	} else {
		return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
			"message": fmt.Sprintf("Product with ID %d not found", id),
		})
	}
}
```

#### routes/main.go

```go
package routes

import (
	"gofiber/src/controllers"

	"github.com/gofiber/fiber/v2"
)

func Router(app *fiber.App) {
	app.Get("/products", controllers.GetAllProducts)
	app.Get("/product/:id", controllers.GetProductById)
	app.Post("/product", controllers.CreateProduct)
	app.Put("/product/:id", controllers.UpdateProduct)
	app.Delete("/product/:id", controllers.DeleteProduct)
}
```

#### main.go

```go
package main

import (
	"gofiber/src/routes"

	"github.com/gofiber/fiber/v2"
)

func main() {
	app := fiber.New()
	routes.Router(app)
	app.Listen(":3000")
}
```

Pastikan untuk mengganti `your_username` dan `project_name` sesuai dengan struktur folder dan nama proyek yang sebenarnya. Dengan struktur folder seperti ini, kode akan lebih terorganisir dan mudah dipelihara.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zakimaliki.gitbook.io/gofiber/basic-backend-dengan-gofiber-part-1/implementasi-mvc-di-gofiber.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
