Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 24, 2021 04:19 pm GMT

Image upload using Golang and React

Golang is a blockbuster server side language in the field of efficiency and concurrency. If you are a Nodejs developer definitely you will come across express js for building your web api services. Gofiber is exactly like the express framework for golang and no doubt it booms with the efficiency of Fasthttp and golang.

In this blog post we will create a simple image upload server using gofiber and we will use reactjs for frontend to select image from file and upload to server.

we will use axios for http request to server and it is really awesome when we deal with implementing authentication and handling lots of api requests. It has lots of features which make life easy when dealing with api in react.

we will use chakra ui for designing material like button , images and layout it shins in Accessibility that directly effect better SEO.

library and tools we will use

  • golang
  • gofiber
  • reactjs
  • axios
  • chakra ui

Setup backend

create new directory and enter into it

mkdir go-react-image-uploadcd go-react-image-upload

create a new directory server inside go-react-image-upload and enter into it

mkdir server cd server

Setup go environment

go mod init github.com/harshmangalam

install packages required for backend

go get  github.com/gofiber/fiber/v2go get github.com/google/uuid

uuid will help to generate unique id so that we can name our image easily and no two image will have same name.

create new go file main.go inside server and start writting code

package mainimport (    "fmt"    "log"    "os"    "strings"    "github.com/gofiber/fiber/v2"    "github.com/gofiber/fiber/v2/middleware/cors"    "github.com/google/uuid")func main() {    // create new fiber instance  and use across whole app    app := fiber.New()    // middleware to allow all clients to communicate using http and allow cors    app.Use(cors.New())    // serve  images from images directory prefixed with /images    // i.e http://localhost:4000/images/someimage.webp    app.Static("/images", "./images")    // handle image uploading using post request    app.Post("/", handleFileupload)    // delete uploaded image by providing unique image name    app.Delete("/:imageName", handleDeleteImage)    // start dev server on port 4000    log.Fatal(app.Listen(":4000"))}func handleFileupload(c *fiber.Ctx) error {    // parse incomming image file    file, err := c.FormFile("image")    if err != nil {        log.Println("image upload error --> ", err)        return c.JSON(fiber.Map{"status": 500, "message": "Server error", "data": nil})    }    // generate new uuid for image name     uniqueId := uuid.New()    // remove "- from imageName"    filename := strings.Replace(uniqueId.String(), "-", "", -1)    // extract image extension from original file filename    fileExt := strings.Split(file.Filename, ".")[1]    // generate image from filename and extension    image := fmt.Sprintf("%s.%s", filename, fileExt)    // save image to ./images dir     err = c.SaveFile(file, fmt.Sprintf("./images/%s", image))    if err != nil {        log.Println("image save error --> ", err)        return c.JSON(fiber.Map{"status": 500, "message": "Server error", "data": nil})    }    // generate image url to serve to client using CDN    imageUrl := fmt.Sprintf("http://localhost:4000/images/%s", image)    // create meta data and send to client    data := map[string]interface{}{        "imageName": image,        "imageUrl":  imageUrl,        "header":    file.Header,        "size":      file.Size,    }    return c.JSON(fiber.Map{"status": 201, "message": "Image uploaded successfully", "data": data})}func handleDeleteImage(c *fiber.Ctx) error {    // extract image name from params    imageName := c.Params("imageName")    // delete image from ./images    err := os.Remove(fmt.Sprintf("./images/%s", imageName))    if err != nil {        log.Println(err)        return c.JSON(fiber.Map{"status": 500, "message": "Server Error", "data": nil})    }    return c.JSON(fiber.Map{"status": 201, "message": "Image deleted successfully", "data": nil})}

run main.go from server

go run main.go

Now our server is up and running we can test it using Postman

postman

setup frontend

come outside from server directory and generate reactjs project using create-react-app

npx create-react-app reactjscd reactjs

install dependencies

npm i @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4 axios

index.js

import React from 'react';import ReactDOM from 'react-dom';import App from './App';ReactDOM.render(  <App />  ,  document.getElementById('root'));

setup App.js

import { Box, ChakraProvider, Container } from "@chakra-ui/react";import Axios from "axios";import Upload from "./components/Upload";Axios.defaults.baseURL = "http://localhost:4000";function App() {  return (    <ChakraProvider>      <Box        minH="100vh"        w="100%"        bg="gray.200"        display="flex"        alignItems="center"        justifyContent="center"      >        <Container maxWidth="container.xl">          <Upload />        </Container>      </Box>    </ChakraProvider>  );}export default App;

create new hook useUpload hook in hooks folder

hooks/useUpload.js

import { useState } from "react";import axios from "axios";import { useToast } from "@chakra-ui/react";const useUpload = () => {  const [image, setImage] = useState(null);  const [loading, setLoading] = useState(false);  const [uploadedImage, setUploadedImage] = useState(null);  const toast = useToast();  const handleChangeImage = (e) => {    setImage(e.target.files[0]);  };  const handleUploadImage = async () => {    try {      setLoading(true);      const formData = new FormData();      formData.append("image", image);      const res = await axios.post("/", formData);      if (res.data.data) {        console.log(res.data);        setUploadedImage(res.data.data);        toast({          title: "Image Uploaded",          description: res.data.message,          status: "success",          duration: 4000,          isClosable: true,        });      }    } catch (error) {      console.log(error);    } finally {      setImage(null);      setLoading(false);    }  };  const handleRemoveImage = async () => {    try {      setLoading(true);      const res = await axios.delete(`/${uploadedImage.imageName}`);      if (res.data) {        console.log(res.data);        setUploadedImage(null);        toast({          title: "Image Deleted",          description: res.data.message,          status: "success",          duration: 4000,          isClosable: true,        });      }    } catch (error) {      console.log(error);    } finally {      setLoading(false);    }  };  return {    image,    uploadedImage,    loading,    handleChangeImage,    handleUploadImage,    handleRemoveImage,  };};export default useUpload;

create Upload.js inside components folder

components/Upload.js

import { Button, Heading, VStack, Image, HStack, Tag } from "@chakra-ui/react";import React from "react";import { useRef } from "react";import useUpload from "../hooks/useUpload";function Upload() {  const imageRef = useRef(null);  const {    loading,    image,    handleRemoveImage,    handleChangeImage,    handleUploadImage,    uploadedImage,  } = useUpload();  return (    <>      <input        style={{ display: "none" }}        type="file"        accept="image/*"        ref={imageRef}        onChange={handleChangeImage}      />      <VStack>        <Heading>Image uploading using Golang and Reactjs</Heading>        <Button          onClick={() => imageRef.current.click()}          colorScheme="blue"          size="lg"        >          Select Image        </Button>      </VStack>      {image && (        <VStack my="4">          <Image            src={URL.createObjectURL(image)}            width="300px"            height="300px"            alt="selected image..."          />          <Button            onClick={handleUploadImage}            variant="outline"            colorScheme="green"            isLoading={loading}          >            Upload          </Button>        </VStack>      )}      {uploadedImage && (        <VStack my="4">          <Image            src={uploadedImage.imageUrl}            width="300px"            height="300px"            alt={uploadedImage.imageName}          />          <HStack>            <Tag variant="outline" colorScheme="blackAlpha">              ~ {Math.floor(uploadedImage.size / 1024)} Kb            </Tag>            <Button              variant="solid"              colorScheme="red"              onClick={handleRemoveImage}              isLoading={loading}            >              Delete            </Button>          </HStack>        </VStack>      )}    </>  );}export default Upload;

1

2

3

4

5


Original Link: https://dev.to/harshmangalam/image-upload-using-golang-and-react-29n1

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To