# Membuat server upload dengan cloudinary di Gofiber

#### Langkah-langkah Implementasi Upload File ke Cloudinary

1. **Tambahkan `cloudinary-go` ke dalam proyek**:
   * Install package `cloudinary-go` dengan menjalankan perintah:

     ```bash
     go get github.com/cloudinary/cloudinary-go
     ```
2. **Buat Helper untuk Upload File ke Cloudinary**:

   * Buat file `cloudinary.go` di dalam direktori `services` untuk menangani proses upload file ke Cloudinary.

   ```go
   // src/services/cloudinary.go

   package services

   import (
       "fmt"
       "mime/multipart"
       "os"
       "path/filepath"
       "time"

       "github.com/cloudinary/cloudinary-go"
       "github.com/cloudinary/cloudinary-go/api/uploader"
       "github.com/gofiber/fiber/v2"
   )

   func UploadCloudinary(c *fiber.Ctx, file *multipart.FileHeader) (*uploader.UploadResult, error) {
       // Menginisialisasi konfigurasi Cloudinary
       cloudinaryURL := os.Getenv("CLOUDINARY_URL")
       if cloudinaryURL == "" {
           return nil, fiber.NewError(fiber.StatusInternalServerError, "Cloudinary URL not found")
       }

       cld, err := cloudinary.NewFromURL(cloudinaryURL)
       if err != nil {
           return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
       }

       // Membuka file
       src, err := file.Open()
       if err != nil {
           return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
       }
       defer src.Close()

       // Menghapus ekstensi dari file.Filename
       ext := filepath.Ext(file.Filename)
       fileNameWithoutExt := file.Filename[:len(file.Filename)-len(ext)]

       // Konfigurasi uploader Cloudinary
       uploadParams := uploader.UploadParams{
           PublicID:  fmt.Sprintf("%d_%s", time.Now().Unix(), fileNameWithoutExt),
           Overwrite: true,
       }

       // Mengunggah file ke Cloudinary
       uploadResult, err := cld.Upload.Upload(c.Context(), src, uploadParams)
       if err != nil {
           return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
       }

       return uploadResult, nil
   }
   ```
3. **Buat Controller untuk Mengelola Upload File ke Cloudinary**:

   * Buat fungsi `UploadFileServer` di `ProductController` untuk menangani permintaan upload file ke Cloudinary.

   ```go
   // src/controllers/ProductController.go

   package controllers

   import (
       "gofiber/src/helpers"
       "gofiber/src/services"
       "github.com/gofiber/fiber/v2"
   )

   func UploadFileServer(c *fiber.Ctx) error {
       // Ambil file dari form
       file, err := c.FormFile("file")
       if err != nil {
           return c.Status(fiber.StatusBadRequest).SendString("Gagal mengunggah file: " + err.Error())
       }

       // Validasi ukuran file (maksimal 2MB)
       maxFileSize := int64(2 << 20) // 2MB
       if err := helpers.SizeUploadValidation(file.Size, maxFileSize); err != nil {
           return err
       }

       // Baca sebagian dari file untuk validasi tipe
       fileHeader, err := file.Open()
       if err != nil {
           return c.Status(fiber.StatusInternalServerError).SendString("Gagal membuka file: " + err.Error())
       }
       defer fileHeader.Close()

       buffer := make([]byte, 512)
       if _, err := fileHeader.Read(buffer); err != nil {
           return c.Status(fiber.StatusInternalServerError).SendString("Gagal membaca file: " + err.Error())
       }

       // Validasi tipe file
       validFileTypes := []string{"image/png", "image/jpeg", "image/jpg", "application/pdf"}
       if err := helpers.TypeUploadValidation(buffer, validFileTypes); err != nil {
           return err
       }

       // Unggah file ke Cloudinary
       uploadResult, err := services.UploadCloudinary(c, file)
       if err != nil {
           return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
       }
       return c.JSON(uploadResult)
   }
   ```
4. **Tambahkan Route untuk Upload File**:

   * Tambahkan route baru untuk mengupload file di file `routes/main.go`.

   ```go
   // src/routes/main.go

   package routes

   import (
       "gofiber/src/controllers"
       "gofiber/src/middlewares"

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

   func Router(app *fiber.App) {
       // Product routes
       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)
       app.Post("/upload", controllers.UploadFile)
       app.Post("/uploadServer", controllers.UploadFileServer)

       // Category routes
       app.Get("/categories", middlewares.JwtMiddleware(), controllers.GetAllCategories)
       app.Get("/category/:id", controllers.GetCategoryById)
       app.Post("/category", controllers.CreateCategory)
       app.Put("/category/:id", controllers.UpdateCategory)
       app.Delete("/category/:id", controllers.DeleteCategory)

       // User Routes
       app.Post("/register", controllers.RegisterUser)
       app.Post("/login", controllers.LoginUser)
       app.Post("/refreshToken", controllers.RefreshToken)
   }
   ```
5. **Konfigurasi Variabel Lingkungan untuk Cloudinary**:

   * Untuk mendapatkan api\_key , api\_secret, dan cloud\_name kunjungi website resmi [cloudinary](https://cloudinary.com/users/register_free) kemudian tambahkan variabel `CLOUDINARY_URL` di file `.env` dengan nilai yang sesuai dengan kredensial Cloudinary Anda.

   ```
   CLOUDINARY_URL=cloudinary://<api_key>:<api_secret>@<cloud_name>
   ```

{% embed url="<https://github.com/zakimaliki/basic_gofiber_part_1/tree/925cfec079ab6198efa1666a71df1ffbaccbf1ab>" %}

Dengan langkah-langkah di atas, Anda telah berhasil mengimplementasikan fitur upload file ke Cloudinary dalam aplikasi Anda menggunakan Fiber dan Golang.
