Using AWS S3 to reduce server latency.

Lincoln munene
5 min readMay 29, 2022

The greater the files or data sets are, the longer it takes to transfer them, regardless of the transfer protocol employed. However, not all data transfer protocols handle huge file transfers the same way, especially in high latency, high bandwidth networks.

Performance optimization is key to the success of any system design. When it comes to maintaining any application, we occasionally need to save user assets such as photographs, pdfs, videos, and so on, and the first thought that comes to mind is to put everything on the server. That is not an issue; in fact, it is the most frequent method of doing so; but, our program will demand us to store a larger number of files or gigantic files at some time. Fortunately, AWS offers a dedicated tool for swiftly and conveniently uploading files to Amazon S3.

I will show you a demo of how to upload these files using laravel framework to your S3 bucket.

Getting Started

We need to create the s3 bucket using this link.

Click on Create Bucket and enter a name (names of the buckets are shared among the entire Amazon S3 network, so if we create a bucket, nobody else can use that name for a new bucket).

Use a region that is close to your system users.

You need to unselect the Block for all public access. This will be used by your application users who need public access to the bucket. Click the create bucket button and your bucket is up and running.

3. Bucket policy

We’ll need to go to this page to create a bucket policy now. To create a good policy, acquire the following picture and choose the operations DeleteObject, GetObject, and PutObject. composer or s3 create-project laravel/laravel laravel s3 –prefer-dist.

Click the Add Statement button and then Generate Policy. Your sample policy should look similar to mine.

{
"Version": "2012-10-17",
"Id": "Policy1653737504555",
"Statement": [
{
"Sid": "Stmt1653737344095",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::mybucketname/*"
}
]
}

This policy will be placed on this page to allow users to publicly access your bucket. Ensure to add your s3 bucket name on the link.

A bucket policy is a resource-based policy that you may use to control who has access to your bucket and its contents. Only the bucket owner has the ability to link a policy to a bucket. The bucket’s permissions are applied to all of the bucket’s items that are owned by the bucket owner. Other AWS accounts’ items are not affected by these rights.

When an item is uploaded to your S3 bucket by another AWS account, that account (the object writer) owns the object, has access to it, and may allow other users access to it via ACLs. Item Ownership may be used to override this default behavior, allowing you to deactivate ACLs and automatically own every object in your bucket as the bucket owner. As a result, policies like IAM policies, S3 bucket policies, virtual private cloud (VPC) endpoint policies, and AWS Organizations' service control policies are used to manage access to your data (SCPs). See Controlling object ownership and deactivating ACLs for your bucket for additional details.

4. Access Key Id and Secret Access Key.

Now we will go there to get our Access Key Id and Secret Access Key to put them on our .env file.

5. Laravel installation.

This is the application we are using to test the s3 bucket. Please read the laravel documentation for more about its installation. You can use the s3 buckets on any type of application including android applications.

composer create-project --prefer-dist laravel/laravel laravel_s3

6. Install the s3 package.

composer require league/flysystem-aws-s3-v3

As a best practice, you should set up your AWS credentials in the .env file to avoid hardcode the config/aws.php., this will keep secure your confidential information.

7.Routes

We need to edit our routes so that we can access the views to upload and display our files.

<?php
Route::get('/', 'FileController@index');
Route::resource('images', 'FileController', ['only' => ['store', 'destroy']]);

Different versions of laravel have got different routing techniques. Check out this link to get the routing based on your installation.

We need to create a FileController to handle these files.

php artisan make:controller FileController

inside the controller insert the code to handle these files.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class FileController extends Controller
{
public function index()
{
$url = 'https://s3.' . env('AWS_DEFAULT_REGION') . '.amazonaws.com/' . env('AWS_BUCKET') . '/';
$images = [];
$files = Storage::disk('s3')->files('images');
foreach ($files as $file) {
$images[] = [
'name' => str_replace('images/', '', $file),
'src' => $url . $file
];
}

return view('welcome', compact('images'));
}

public function store(Request $request)
{
$this->validate($request, [
'image' => 'required|image|max:2048'
]);

if ($request->hasFile('image')) {
$file = $request->file('image');
$name = time() . $file->getClientOriginalName();
$filePath = 'images/' . $name;
Storage::disk('s3')->put($filePath, file_get_contents($file));
}

return back()->withSuccess('Image uploaded successfully');
}

public function destroy($image)
{
Storage::disk('s3')->delete('images/' . $image);

return back()->withSuccess('Image was deleted successfully');
}
}

Finally, we need to create the welcome.blade.php

<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel S3</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">
<style>
body, .card{
background: #ededed;
}
</style>
</head>
<body>
<div class="container">
<div class="row pt-5">
<div class="col-sm-12">
@if ($errors->any())
<div class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert">×</button>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if (Session::has('success'))
<div class="alert alert-info">
<button type="button" class="close" data-dismiss="alert">×</button>
<p>{{ Session::get('success') }}</p>
</div>
@endif
</div>
<div class="col-sm-8">
@if (count($images) > 0)
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
@foreach ($images as $image)
<div class="carousel-item {{ $loop->first ? 'active' : '' }}">
<img class="d-block w-100" src="{{ $image['src'] }}" alt="First slide">
<div class="carousel-caption">
<form action="{{ url('images/' . $image['name']) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" class="btn btn-default">Remove</button>
</form>
</div>
</div>
@endforeach
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
@else
<p>Nothing found</p>
@endif
</div>
<div class="col-sm-4">
<div class="card border-0 text-center">
<form action="{{ url('/images') }}" method="POST" enctype="multipart/form-data" class="form-horizontal">
{{ csrf_field() }}
<div class="form-group">
<input type="file" name="image" id="image">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Upload</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
</body>
</html>

Conclusion.

That is a simple demonstration of how to upload to s3 bucket using laravel. This is also applicable to android code and the process is similar, just modification of codes.

For more clarification, contact me via Whatsapp at +254704800563.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response