In this article, we’ll guide you through creating a simple yet effective file download API using Go and the Gorilla Mux library. This API demonstrates a basic implementation, laying the groundwork for more robust file download functionalities in your Go applications.
Prerequisites:
- Basic understanding of Go programming
- Familiarity with HTTP concepts
What We’ll Build:
We’ll build a Go API endpoint that allows users to download files stored in a designated directory.
Code Breakdown:
import (
"file-upload-go/domain" // Replace with your domain model if applicable
"file-upload-go/handlers" // Replace with your handler package if applicable
"file-upload-go/services" // Replace with your service package if applicable
"fmt"
"net/http"
"github.com/gorilla/mux"
"path/filepath" // Added for file path manipulation
"os" // Added for file operations
)
fmt
for formatting outputnet/http
for handling HTTP requests/responsesgithub.com/gorilla/mux
for routingpath/filepath
for file path manipulationos
for file operations (opening files)
Router and Route Definition:
router := mux.NewRouter()
router.HandleFunc("/download/{filename}", FileDownload).Methods(http.MethodGet)
- We create a new router instance using
mux.NewRouter()
.
We define a route for file download using router.HandleFunc
.
- The route path is
/download/{filename}
, where{filename}
is a variable that captures the filename from the URL. - The
FileDownload
function handles GET requests on this route.
FileDownload Function:
func (uh UploadHandler) FileDownload(w http.ResponseWriter, r *http.Request) {
filename := mux.Vars(r)["filename"]
w.Header().Set("Content-Type", "application/json") // Initial Content-Type
directory := filepath.Join("downloadable", filename)
_, err := os.Open(directory)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
json.NewEncoder(w).Encode("Unable to open file ")
return
}
// Set download headers:
w.Header().Set("Content-Disposition", "attachment; filename="+filepath.Base(directory))
w.Header().Set("Content-Type", "application/octet-stream") // Set binary stream type
// Serve the file
http.ServeFile(w, r, directory)
return
}
- The
FileDownload
function handles GET requests on the/download/{filename}
path. - We extract the filename from the URL using
mux.Vars(r)["filename"]
. - Initially, we set the
Content-Type
header toapplication/json
(can be adjusted based on needs). - We construct the file path using
filepath.Join
and attempt to open the file withos.Open
. - On error (unable to open file), we set an internal server error status code and return an error message.
- You can customize error handling here.
- We set appropriate headers for file download:
Content-Disposition: attachment; filename={filename}
: Instructs the browser to download the file as an attachment and specifies the filename.Content-Type: application/octet-stream
: Indicates a binary stream, suitable for most file types.- Finally, we use
http.ServeFile
to serve the file content from the specified directory (directory
).
Here’s a cURL command to test your file download API:
curl -X GET http://localhost:8080/download/report.pdf
Explanation:
-X GET
: Specifies a GET request.http://localhost:PORT/download/your_filename
: The URL of your download endpoint with the filename.
If the file download is successful, you should see the file content in your terminal or have it saved to your local system, depending on your system’s default behavior for file downloads.
Note: If you have a browser installed, you can also directly access the download URL in your browser’s address bar to trigger the download.
Learn more [GO] Building a File Download API in Go