Home Categories
How To Upload Single and Multiple Files
in Golang
May 4, 2023 0 Comments 37
This article will teach you how to upload single and multiple files on a
Golang web server. The tutorial focuses on image upload, but the concepts
can be extended and used for any file type.
···
Now Playing
Node.Js + Prisma + Post…
Node.Js + Prisma + Postgresql Access & Refresh Toke…
When building APIs for either Web, Mobile, or Desktop apps, very often, the
need to make provision for file upload arises. Therefore, knowing how to
upload and process files in Golang will give you more confidence when
searching for jobs.
At the end of this comprehensive guide, you should know how to:
Upload a single image and store it on the disk
Upload multiple images and store them on the disk
Upload and resize a single image before storing it on the disk
Upload and resize multiple images before storing them on the disk
More practice:
How to Implement Two-factor Authentication (2FA) in React.js
How to Implement Two-factor Authentication (2FA) in Node.js
Two-factor Authentication (2FA) in FastAPI and Python
How to Implement (2FA) Two-factor Authentication in Golang
Table of Contents
Prerequisites
While this tutorial is designed to be beginner friendly, these are the
prerequisites the reader is expected to possess:
···
Have the latest version of Golang installed on your system
Have basic knowledge of Golang
Have a basic understanding of API architectures
Basic knowledge of Gin Gonic will be beneficial
Run the Golang File Upload Project Locally
1. If you don’t have Golang installed, visit https://go.dev/doc/install to
download and install the binary executable on your machine.
2. Download or clone the Upload Single and Multiple Files in Golang
source code from https://github.com/wpcodevo/file_upload_golang
3. Open the integrated terminal in your IDE and run go mod tidy to
install all the necessary packages.
4. Start the Gin Gonic HTTP server with go run main.go or use the
https://github.com/cosmtrek/air library if you need the hot-reloading
feature.
5. Open an API testing software or visit http://localhost:8000 to
upload the files.
Step 1 – Setup the Golang Project
To get started, navigate to the location you would like to set up the project
and create a folder named file_upload_golang . Once the directory has
been created, open it with an IDE or text editor like VS Code.
1 mkdir file_upload_golang && cd file_upload_golang && code .
Next, initialize the Golang project by running:
1 go mod init github.com/:github_username/name_of_project
Now that you’ve created the project module, install the Gin Gonic package
with this command. Gin Gonic is an HTTP web framework written in Go.
1 go get -u github.com/gin-gonic/gin
Next, create a main.go file and add the following code snippets:
main.go
1 package main
2
3 import (
4 "github.com/gin-gonic/gin"
5 )
6
7 func main() {
8 router := gin.Default()
9
10 router.GET("/healthchecker", func(ctx *gin.Context) {
11 ctx.JSON(200, gin.H{"status": "success", "message": "How to Upload Sing
12 })
13
14 router.Run(":8000")
15 }
16
The above code will create a Gin Gonic engine instance, add a health
checker route to the middleware pipeline and start the HTTP server on port
8000. Start the Gin server by running go run main.go .
Open a new tab in your browser and visit
http://localhost:8000/healthchecker to see the JSON object sent by
the Golang API.
Congrats if you have made it this far. We will continue by creating the file
upload components with HTML, CSS, and JavaScript. After that, we will use
Gin Gonic to parse and render the HTML markup.
Step 2 – Create the File Upload Components
Below is a preview of the file upload components. The HTML markup will
have three components:
OFERTAS DO CONSUMIDOR
OS DESCONTOS
CHEGARAM
Ver Ofertas
Beyond Fast
Image preview area
Single file upload component
Multiple file upload component
X
FileuploadinGolang X +
ocalhost:8000
HowtoSetup tRPCCRUD TS
Golang
Forget/Reset
SQLC Reset
Golang
Password
API NEXT.
Password
JWT GOFileUpload
Authentication
CRUD TS
Authorization mongoDB GraphQLAPI ЛЕХТ.
SingleFileUpload
ChooseFileNofilechosen
MultipleFileUpload
ChooseFiles7files
To spin up the file upload components, create a templates/index.html
file and add the following HTML markup.
templates/index.html
90 imgHolder.appendChild(imgElement);
91 IMAGE_PREVIEW.appendChild(imgHolder);
92 } catch (error) {
93 alert(error.message);
94 }
95 });
96
97 // Mulitple File Upload
98 document
99 .getElementById("mulitple_files_upload")
100 .addEventListener("change", async (event) => {
101 try {
102 let formData = new FormData();
103 for (let key in event.target.files) {
104 formData.append("images", event.target.files[key]);
105 }
106 const data = await fetch(`${SERVER_ENDPOINT}/upload/multiple
107 body: formData,
108 method: "POST",
109 }).then((res) => res.json());
110
111 data.filepaths.forEach((filepath) => {
112 const imgHolder = document.createElement("div");
113 const imgElement = document.createElement("img");
114 imgHolder.classList.add("file-preview__el");
115 imgElement.classList.add("file-preview__img");
116 imgElement.src = filepath;
117 imgHolder.appendChild(imgElement);
118 IMAGE_PREVIEW.appendChild(imgHolder);
119 });
120 } catch (error) {
121 alert(error.message);
122
123 }
124 });
125 </script>
126 </body>
</html>
Quite a lot is happening in the above code, let’s break it down:
First, we created a basic markup that contains the file upload
components and some basic styling to improve the visual appearance
of the components.
Then, we wrote some logic to upload single and multiple files with
JavaScript.
Finally, we wrote some logic with JavaScript to dynamically display the
images after the files have been saved to the disk.
Now that we have the HTML template, let’s write some code to render
index.html on the root route. Open main.go file and replace its content
with the code below.
main.go
1 package main
2
3 import (
4 "net/http"
5
6 "github.com/gin-gonic/gin"
7 )
8
9 func main() {
10 router := gin.Default()
11
12 router.LoadHTMLGlob("templates/*")
13 router.GET("/healthchecker", func(ctx *gin.Context) {
14 ctx.JSON(200, gin.H{"status": "success", "message": "How to Upload Sing
15 })
16
17 router.GET("/", func(ctx *gin.Context) {
18 ctx.HTML(http.StatusOK, "index.html", nil)
19 })
20 router.Run(":8000")
21 }
22
After that, start the Gin HTTP server with go run main.go and open
http://localhost:8000/ in a new tab to see the rendered HTML.
Let’s go ahead and write the code required for uploading and processing
the files.
Step 3 – Upload a Single File in Golang
In this section, you will create a route function to retrieve the uploaded file
and store it in the filesystem. Handling file upload in Golang can be a little
challenging especially when you are a beginner. Luckily, Gin provides a
simple way to handle uploaded files and store them on the disk.
To handle
a single file, we will use Gin’s .FromFile() method that’s
available on the context object to retrieve the uploaded file from the multi-
part content.
main.go
1 func uploadSingleFile(ctx *gin.Context) {
2
file, header, err := ctx.Request.FormFile("image")
3 if err != nil {
4
ctx.String(http.StatusBadRequest, fmt.Sprintf("file err : %s"
5 return
6 }
7
8 fileExt := filepath.Ext(header.Filename)
9 originalFileName := strings.TrimSuffix(filepath.Base(header.Filename
10 now := time.Now()
11 filename := strings.ReplaceAll(strings.ToLower(originalFileName
12 filePath := "http://localhost:8000/images/single/" + filename
13
14 out, err := os.Create("public/single/" + filename)
15 if err != nil {
16 log.Fatal(err)
17 }
18 defer out.Close()
19 _, err = io.Copy(out, file)
20 if err != nil {
21 log.Fatal(err)
22 }
23 ctx.JSON(http.StatusOK, gin.H{"filepath": filePath})
24 }
Let’s evaluate the above code. First, we attempt to retrieve the file with the
name “image” from the multi-part content and check if the file is received
successfully. To avoid conflicts with the file names, we appended a Unix
time to the original file name, called the os.Create() method to create
the file in the public/single/ directory, and used an if statement to
check if the file has been created.
Conheça DESCONTO
EXTRA
lugares
RESERVE AGORA
10 % CÓDIGO: LATAMBR10
After that, we called the io.Copy() method to copy the uploaded file to
incríveis
#StaySafewithMelia
the file system at the specified destination. If everything goes well, and the
file was stored on the disk, we will return the file path to the client.
I didn’t use Gin’s ctx.SaveUploadedFile(file, dst) method
because it had some limitations.
Step 4 – Resize a Single File in Golang
Now let’s handle the case where we want to process the uploaded file
before storing it in the file system. Since we are dealing with images, we will
use the https://github.com/disintegration/imaging package to process
the uploaded image before storing it on the disk.
To begin, open your terminal and install the Imaging package.
···
1 go get -u github.com/disintegration/imaging
The Imaging package provides a bunch of image processing functions but
we will only use the .Resize() function to reduce the complexity of the
project. Before we can resize the image, we first need to retrieve the file
from the multi-part content with the .FormFile() method, generate a
Unix time, and append it to the filename.
After that, we will call the image.Decode() method to decode the file from
multipart.File to image.Image . If everything goes on well, we will resize
the image to a specific aspect ratio by utilizing the imaging.Resize()
function.
···
Read the Imaging documentation for more details about the
various resampling filters supported by the imaging.Resize()
function.
Once the image has been resized and there is no error, we will call the
imaging.Save() method to save the image on the disk at the specified
destination.
···
main.go
1 func uploadResizeSingleFile(ctx *gin.Context) {
2 file, header, err := ctx.Request.FormFile("image")
3 if err != nil {
4 ctx.String(http.StatusBadRequest, fmt.Sprintf("file err : %s"
5 return
6 }
7
8 fileExt := filepath.Ext(header.Filename)
9 originalFileName := strings.TrimSuffix(filepath.Base(header.Filename
10 now := time.Now()
11 filename := strings.ReplaceAll(strings.ToLower(originalFileName
12 filePath := "http://localhost:8000/images/single/" + filename
13
14 imageFile, _, err := image.Decode(file)
15 if err != nil {
16 log.Fatal(err)
17 }
18 src := imaging.Resize(imageFile, 1000, 0, imaging.Lanczos)
19 err = imaging.Save(src, fmt.Sprintf("public/single/%v", filename
20 if err != nil {
21 log.Fatalf("failed to save image: %v", err)
22 }
23
24 ctx.JSON(http.StatusOK, gin.H{"filepath": filePath})
25 }
Step 5 – Upload Multiple Files in Golang
Now let’s handle the case where the client uploads multiple files to the
server. To do that, we will create a route function that will extract the files
from the multipart content, modify the origin filenames, and save the files
to the filesystem. We can manually parse and iterate over each file but Gin
provides a ctx.MultipartForm() function that can parse the multipart
form and the uploaded files.
···
main.go
1 func uploadMultipleFile(ctx *gin.Context) {
2 form, _ := ctx.MultipartForm()
3 files := form.File["images"]
4 filePaths := []string{}
5 for _, file := range files {
6 fileExt := filepath.Ext(file.Filename)
7 originalFileName := strings.TrimSuffix(filepath.Base(file.
8 now := time.Now()
9 filename := strings.ReplaceAll(strings.ToLower(originalFileName
10 filePath := "http://localhost:8000/images/multiple/" + filename
11
12 filePaths = append(filePaths, filePath)
13 out, err := os.Create("./public/multiple/" + filename)
14 if err != nil {
15 log.Fatal(err)
16 }
17 defer out.Close()
18
19 readerFile, _ := file.Open()
20 _, err = io.Copy(out, readerFile)
21 if err != nil {
22 log.Fatal(err)
23 }
24 }
25
26 ctx.JSON(http.StatusOK, gin.H{"filepath": filePaths})
27 }
We parsed the uploaded files by calling Gin’s ctx.MultipartForm()
method and stored the result in a form variable. Then, we extracted the
multipart content with the name images from form.File[] , looped
through the list of files, modified the filenames, and stored the files on the
disk.
···
If everything goes well and the files were stored in the filesystem, a slice
holding the file paths will be returned to the client.
···
···
Step 6- Resize Multiple Files in Golang
This route handler is similar to the uploadMultipleFile function but this
time we will resize the images before storing them in the filesystem. After
looping through the multipart files, Imaging‘s image.Decode() method will
be called to decode the images from multipart.File to image.Image .
···
If the images were decoded successfully, the imaging.Resize() method will
be evoked to crop each image before the imaging.Save() method will be
called to save the file to the filesystem.
main.go
···
1 func uploadResizeMultipleFile(ctx *gin.Context) {
2 form, _ := ctx.MultipartForm()
3 files := form.File["images"]
4 filePaths := []string{}
5 for _, file := range files {
6 fileExt := filepath.Ext(file.Filename)
7 originalFileName := strings.TrimSuffix(filepath.Base(file.
8 now := time.Now()
9 filename := strings.ReplaceAll(strings.ToLower(originalFileName
10 filePath := "http://localhost:8000/images/multiple/" + filename
11
12 filePaths = append(filePaths, filePath)
13 readerFile, _ := file.Open()
14 imageFile, _, err := image.Decode(readerFile)
15 if err != nil {
16 log.Fatal(err)
17 }
18 src := imaging.Resize(imageFile, 1000, 0, imaging.Lanczos)
19 err = imaging.Save(src, fmt.Sprintf("public/multiple/%v", filename
20 if err != nil {
21 log.Fatalf("failed to save image: %v", err)
22 }
23 }
24
25 ctx.JSON(http.StatusOK, gin.H{"filepath": filePaths})
26 }
Step 7 – Register the Routes
Now let’s create routes to evoke the route handlers. The API will have four
routes:
/ – Renders the HTML template on the root route
/images – A route for accessing the files stored in the filesystem
/upload/single – Upload a single file
/upload/multiple – Uploads multiple files
Because the files are to be stored on the disk, we need to create folders that
represent the folder structure we passed to the os.Create() and
imaging.Save() methods. To do that, we will utilize an init function to
create the folders if they don’t exists before the main function gets called.
main.go
1 package main
2
3 import (
4 "errors"
5 "fmt"
6 "image"
7 "io"
8 "log"
9 "net/http"
10 "os"
11 "path/filepath"
12 "strings"
13 "time"
14
15 "github.com/gin-gonic/gin"
16
17 "github.com/disintegration/imaging"
18 )
19
20 func uploadResizeSingleFile(ctx *gin.Context) {
21 file, header, err := ctx.Request.FormFile("image")
22 if err != nil {
23 ctx.String(http.StatusBadRequest, fmt.Sprintf("file err : %s"
24 return
25 }
26
27 fileExt := filepath.Ext(header.Filename)
28 originalFileName := strings.TrimSuffix(filepath.Base(header.Filename
29 now := time.Now()
30 filename := strings.ReplaceAll(strings.ToLower(originalFileName
31 filePath := "http://localhost:8000/images/single/" + filename
32
33 imageFile, _, err := image.Decode(file)
34 if err != nil {
35 log.Fatal(err)
36 }
37 src := imaging.Resize(imageFile, 1000, 0, imaging.Lanczos)
After implementing all the above code, start the Gin HTTP server by running
go run main.go .
···
Conclusion
Congrats! You have made it to the end, and I hope you’ve learned how to
upload and process files in Golang. Take it up as a challenge, add more
file-processing features, and perhaps do something even more awesome
with the knowledge obtained from this tutorial.
You can find the complete code on GitHub.
Download Source Code
Share Article:
https://codevoweb.com/how-to-upload-single-and-multiple-files-in-golang/
Tags: Golang Golang API
May 28, 2023
Two-factor Authentication (2FA) in FastAPI and Python
May 4, 2023
How To Setup and Use Prisma in Deno
Leave a Reply
Comment
Name Email
Save my name, email, and website in this browser for the next time I comment.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of
Service apply.
Post Comment
This site uses Akismet to reduce spam. Learn how your comment data is processed.
Support Me!
···
Recent posts
February 10, 2024
Setting up Drizzle ORM with NextAuth.js in Next.js 14
February 7, 2024
Set up Google and GitHub OAuth with NextAuth in Next.js 14
February 7, 2024
Implement Authentication with NextAuth in Next.js 14
February 5, 2024
Setup and Use NextAuth.js in Next.js 14 App Directory
Categories
C# (2)
C++ (1)
CSS / SCSS (3)
Deno (8)
Golang (28)
JavaScript (4)
NextJs (36)
NodeJS (32)
Programming (19)
Python (17)
React (35)
Rust (31)
Svelte (5)
Vue (7)
···
Tag Cloud
.NET C# create website Deno developers Django DOM
DOM methods fastapi Golang Golang API graphql gRPC API
html template JavaScript JavaScript DOM landing page
Material-UI Material UI MUI NextJs nodejs nodejs api
Prisma programmers programming language programming terms
pure nodejs api python python development React
React Hook Form ReactJs React Query RTK Query Rust Svelte
SvelteKit TypeScript vscode vscode extension
vscode tips and tricks VueJs website Yew.rs
Copyright @ 2024 CodevoWeb
Privacy Policy | Terms & Conditions | About Us | Sitemap | Contact Us
WordPress Theme by EstudioPatagon
···