help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
go-rest-api
/
internal
/
handlers
RSK World
go-rest-api
Go REST API - Enterprise-grade REST API with JWT Authentication + PostgreSQL + Redis Caching + Docker + Comprehensive Testing + Educational Design
handlers
  • api_handler.go1.4 KB
  • auth_handler.go4.4 KB
  • auth_handler_test.go4.6 KB
  • category_handler.go5.2 KB
  • product_handler.go8.8 KB
  • upload_handler.go5 KB
upload_handler.go
internal/handlers/upload_handler.go
Raw Download
Find: Go to:
/*
* Author: RSK World
* Email: help@rskworld.in / support@rskworld.in
* Website: https://rskworld.in/contact.php
* Year: 2026
*/

package handlers

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"github.com/rskworld/go-rest-api/internal/config"
	"github.com/rskworld/go-rest-api/internal/database"
	"github.com/rskworld/go-rest-api/internal/models"
	"github.com/rskworld/go-rest-api/internal/response"
)

type UploadHandler struct {
	Config *config.Config
}

func NewUploadHandler(cfg *config.Config) *UploadHandler {
	return &UploadHandler{Config: cfg}
}

// UploadProductImage godoc
// @Summary Upload product image
// @Description Upload an image for a specific product
// @Tags uploads
// @Accept  multipart/form-data
// @Produce  json
// @Param id path int true "Product ID"
// @Param image formData file true "Product image file"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Failure 404 {object} response.Response
// @Failure 500 {object} response.Response
// @Security BearerAuth
// @Router /products/{id}/upload [post]
func (h *UploadHandler) UploadProductImage(c *gin.Context) {
	productID := c.Param("id")

	// Check if product exists
	var product models.Product
	if result := database.DB.First(&product, productID); result.Error != nil {
		response.NotFound(c, "Product")
		return
	}

	// Get uploaded file
	file, header, err := c.Request.FormFile("image")
	if err != nil {
		response.ValidationError(c, "No image file provided")
		return
	}
	defer file.Close()

	// Validate file size
	if header.Size > h.Config.MaxFileSize {
		response.ValidationError(c, "File size too large. Maximum size is 5MB")
		return
	}

	// Validate file type
	contentType := header.Header.Get("Content-Type")
	isAllowed := false
	for _, allowedType := range h.Config.AllowedTypes {
		if contentType == allowedType {
			isAllowed = true
			break
		}
	}

	if !isAllowed {
		response.ValidationError(c, "File type not allowed. Only JPEG, PNG, GIF, and WebP are supported")
		return
	}

	// Create upload directory if it doesn't exist
	if err := os.MkdirAll(h.Config.UploadPath, 0755); err != nil {
		response.InternalServerError(c, "Failed to create upload directory")
		return
	}

	// Generate unique filename
	ext := filepath.Ext(header.Filename)
	if ext == "" {
		// Try to determine extension from content type
		switch contentType {
		case "image/jpeg":
			ext = ".jpg"
		case "image/png":
			ext = ".png"
		case "image/gif":
			ext = ".gif"
		case "image/webp":
			ext = ".webp"
		default:
			ext = ".jpg"
		}
	}

	filename := fmt.Sprintf("%s_%d_%d%s", uuid.New().String(), product.ID, time.Now().Unix(), ext)
	filepath := filepath.Join(h.Config.UploadPath, filename)

	// Save file
	if err := c.SaveUploadedFile(header, filepath); err != nil {
		response.InternalServerError(c, "Failed to save image file")
		return
	}

	// Update product with image path
	oldImage := product.Image
	product.Image = "/uploads/" + filename

	if err := database.DB.Model(&product).Update("image", product.Image).Error; err != nil {
		// Clean up uploaded file if database update fails
		os.Remove(filepath)
		response.InternalServerError(c, "Failed to update product image")
		return
	}

	// Remove old image file if it exists
	if oldImage != "" {
		oldFilepath := strings.TrimPrefix(oldImage, "/uploads/")
		oldFilepath = filepath.Join(h.Config.UploadPath, oldFilepath)
		os.Remove(oldFilepath)
	}

	response.Success(c, http.StatusOK, "Image uploaded successfully", gin.H{
		"product_id": product.ID,
		"image_url":  product.Image,
	})
}

// DeleteProductImage godoc
// @Summary Delete product image
// @Description Delete the image of a specific product
// @Tags uploads
// @Accept  json
// @Produce  json
// @Param id path int true "Product ID"
// @Success 200 {object} response.Response
// @Failure 404 {object} response.Response
// @Failure 500 {object} response.Response
// @Security BearerAuth
// @Router /products/{id}/image [delete]
func (h *UploadHandler) DeleteProductImage(c *gin.Context) {
	productID := c.Param("id")

	// Check if product exists
	var product models.Product
	if result := database.DB.First(&product, productID); result.Error != nil {
		response.NotFound(c, "Product")
		return
	}

	if product.Image == "" {
		response.NotFound(c, "Product image")
		return
	}

	// Delete image file
	imagePath := strings.TrimPrefix(product.Image, "/uploads/")
	imagePath = filepath.Join(h.Config.UploadPath, imagePath)
	if err := os.Remove(imagePath); err != nil && !os.IsNotExist(err) {
		response.InternalServerError(c, "Failed to delete image file")
		return
	}

	// Update product to remove image reference
	if err := database.DB.Model(&product).Update("image", "").Error; err != nil {
		response.InternalServerError(c, "Failed to update product")
		return
	}

	response.Success(c, http.StatusOK, "Image deleted successfully", nil)
}
187 lines•5 KB
go

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer