Building a Laravel Package: Lessons from S3Uploader

Building a Laravel package can solve specific problems while enhancing reusability and scalability in applications. S3Uploader serves as an example of how a Laravel package simplifies secure file uploads to Amazon S3 by leveraging pre-signed URLs. Here’s how this package was developed.

S3Uploader Overview

S3Uploader streamlines secure file uploads to Amazon S3 by generating pre-signed URLs, allowing direct file uploads without temporary storage on application servers. This approach enhances security, minimizes server load, and boosts scalability. Sensitive configurations, including AWS credentials, are securely managed using environment variables, ensuring a reliable and secure integration.

Steps Taken to Develop the Package

1. Purpose Definition

S3Uploader was designed to:

  • Generate pre-signed URLs for direct file uploads to S3 bucket.
  • Facilitate file uploads using those URLs securely and efficiently.

2. Directory Structure Organization

The package followed a standard structure:

s3uploader/
├── src/
│   ├── Services/
│   │   └── S3Service.php
│   ├── config/
│   │   └── s3Uploader.php
│   └── S3UploaderServiceProvider.php
├── composer.json
├── .env
├── README.md

3. Core Logic in S3Service

The core functionality of the package is implemented in the S3Service class:

public function __construct()
    {
        $this->s3Client = new S3Client([
            'region' => config('s3Uploader.s3_region'),
            'version' => 'latest',
            'credentials' => [
                'key' => config('s3Uploader.s3_key'),
                'secret' => config('s3Uploader.s3_secret'),
            ],
        ]);

        $this->bucket = config('s3Uploader.s3_bucket');
    }
public function generatePresignedUrl($files): array
    {
        $urls = [];
        foreach ($files as $file) {
            $key = 'uploads/' . $file->getClientOriginalName();
            $cmd = $this->s3Client->getCommand('PutObject', [
                'Bucket' => $this->bucket,
                'Key' => $key,
                'ContentType' => $file->getMimeType()
            ]);

            $request = $this->s3Client->createPresignedRequest($cmd, '+15 minutes');
            $urls[] = [
                'url' => (string) $request->getUri(),
                'key' => $key,
            ];
        }

        return $urls;
    }

4. Configuration Publishing

Use the boot method in your service provider to enable publishing configuration files:

public function boot()
{
    $this->publishes([
        __DIR__ . '/config/s3Uploader.php' => config_path('s3Uploader.php'),
    ], 'config');
}

This allows users to customize the package configuration by running:

php artisan vendor:publish --tag=config

The configuration file includes placeholders for environment variables like:

return [
    's3_region' => env('S3_REGION'),
    's3_key' => env('S3_KEY'),
    's3_secret' => env('S3_SECRET'),
    's3_bucket' => env('S3_BUCKET'),
];

By following the steps outlined above, you can develop a Laravel package like S3Uploader that simplifies tasks and enhances developer productivity. Start small, focus on solving a specific problem, and iterate based on feedback. Happy coding!

Source: https://github.com/bibekdhakal/aws-bulk-upload-presigned-url

Leave a Reply

Your email address will not be published. Required fields are marked *