BIJAY DASSoftware Developer

Advanced S3 File Upload Strategies in Laravel: Beyond the Basics

Published on December 1, 2024

Introduction

As seasoned developers with over a decade of experience, we understand that file uploads are more than just a simple task. When it comes to scaling applications and managing cloud storage, Amazon S3 has become the go-to solution for robust file management.

Prerequisites

Before diving in, ensure you have:

  • Laravel 9+

  • AWS IAM credentials

  • Composer

  • Basic understanding of cloud storage concepts

Step-by-Step Implementation

Package Installation

This library allows Laravel to use AWS S3 as a storage driver.

composer require league/flysystem-aws-s3-v3 "^3.0"

AWS Configuration

Update your .env file with AWS credentials:

AWS_ACCESS_KEY_ID=your_access_key AWS_SECRET_ACCESS_KEY=your_secret_key AWS_DEFAULT_REGION=ap-south-1 AWS_BUCKET=your-bucket-name

File upload service

<?php

namespace App\Services;

use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Storage; use Symfony\Component\HttpFoundation\File\Exception\UploadException;

class FileUploadService

{ /** * Upload file to S3 * * @param UploadedFile $file * @param string $path * * @return string */ public function upload(UploadedFile $file, string $path = '/'): string

{ $this->validate($file); $filename = time() . '_' . uniqid() . '_' . $file->getClientOriginalName(); try { return Storage::disk('s3')->putFileAs($path, $file, $filename); } catch (\Exception $exception) { throw new UploadException('Failed to upload file', 0, $exception); } } private function validate(UploadedFile $file): void

{ $maxFileSize = 10 * 1024 * 1024; // 10MB $allowedTypes = ['jpg', 'png', 'pdf', 'docx']; if ($file->getSize() > $maxFileSize) { throw new \InvalidArgumentException('File too large'); } if (!in_array($file->getClientOriginalExtension(), $allowedTypes)) { throw new \InvalidArgumentException('Invalid file type'); } } }

Controller Implementation

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request; use App\Services\FileUploadService; use Illuminate\Http\JsonResponse;

class FileUploadController extends Controller { public function upload(Request $request, FileUploadService $fileUploadService): JsonResponse { $file = $request->file('file'); try { $result = $fileUploadService->upload($file); return response()->json(['result' => $result]); } catch (\Exception $e) { return response()->json(['error' => $e->getMessage()]); } } }

Security Considerations

  • Use IAM roles with least privilege

  • Enable encryption at rest

  • Implement strict file type validation

  • Use temporary credentials

Monitoring and Logging

Integrate AWS CloudWatch for:

  • Upload success/failure rates

  • File size tracking

  • Performance metrics

Common Pitfalls to Avoid

  • Hardcoding AWS credentials

  • Ignoring file size limits

  • Lack of error handling

  • Not using unique filenames

Additional Resources

Bijay's Image

bijaydas.com