[GO] Building a File Download API in Go

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 output
  • net/http for handling HTTP requests/responses
  • github.com/gorilla/mux for routing
  • path/filepath for file path manipulation
  • os 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 to application/json (can be adjusted based on needs).
  • We construct the file path using filepath.Join and attempt to open the file with os.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

Leave a Reply