DEV Community

Cover image for Creating a GoLang API that allows uploading files to an Amazon S3 bucket
Ayas Hussein
Ayas Hussein

Posted on

Creating a GoLang API that allows uploading files to an Amazon S3 bucket

Step 1: Setup AWS S3

  1. Log in to your AWS Management Console.
  2. Navigate to S3 and create a bucket or you can use any that has been already created. Step 2: Initialize Your Go Project Create a folder / dir and run below commands
go mod init s3-upload-api
go get github.com/aws/aws-sdk-go-v2 github.com/aws/aws-sdk-go-v2/config github.com/aws/aws-sdk-go-v2/service/s3
go get github.com/gorilla/mux

Enter fullscreen mode Exit fullscreen mode

Step 3: Create the API

package main

import (
    "context"
    "fmt"
    "log"
    "mime/multipart"
    "net/http"
    "os"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/gorilla/mux"
)

var (
    s3Client   *s3.Client
    bucketName = "your-bucket-name" // Replace with your S3 bucket name
    region     = "your-region"     // Replace with your S3 bucket region
)

// initializeS3Client initializes the S3 client
func initializeS3Client() {
    cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }
    s3Client = s3.NewFromConfig(cfg)
}

// uploadToS3 uploads a file to S3
func uploadToS3(file multipart.File, fileName string) error {
    _, err := s3Client.PutObject(context.TODO(), &s3.PutObjectInput{
        Bucket: &bucketName,
        Key:    &fileName,
        Body:   file,
    })
    return err
}

// uploadHandler handles file uploads
func uploadHandler(w http.ResponseWriter, r *http.Request) {
    // Parse the incoming request
    err := r.ParseMultipartForm(10 << 20) // Limit upload size to 10MB
    if err != nil {
        http.Error(w, "Unable to parse form", http.StatusBadRequest)
        return
    }

    file, handler, err := r.FormFile("file")
    if err != nil {
        http.Error(w, "Unable to retrieve file", http.StatusBadRequest)
        return
    }
    defer file.Close()

    // Upload file to S3
    err = uploadToS3(file, handler.Filename)
    if err != nil {
        http.Error(w, fmt.Sprintf("Failed to upload file: %v", err), http.StatusInternalServerError)
        return
    }

    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "File uploaded successfully: %s", handler.Filename)
}

func main() {
    initializeS3Client()

    r := mux.NewRouter()
    r.HandleFunc("/upload", uploadHandler).Methods("POST")

    port := "8080"
    log.Printf("Starting server on port %s...", port)
    log.Fatal(http.ListenAndServe(":"+port, r))
}

Enter fullscreen mode Exit fullscreen mode

Step 4: Test the API

go run main.go
Enter fullscreen mode Exit fullscreen mode

Now you are able to send a POST request to http://localhost:8080/upload
with a file name. Try this in postman or your frontend app.

Top comments (0)