Upload File to S3 Bucket API Using AWS .Net SDK
AWS has become an integral part of many software projects as it offers a wide variety of services that could help any project achieve their goals. The S3 bucket is one of those services.
Let's create this API using traditional clean architecture and not using CQRS or MediatR like my previous post. Just because Command and Query offer a looser coupling but in smaller scale projects with not that much business logic and entity operations it wouldn't make sense to keep creating 2+ classes every time you would want to add a new entity action.
So, let's start up with an interface for our AWS services class.
Interface
First, we add an interface so that the controller can use to call the upload service after providing it with a bucket name, path inside the bucket and of course the file itself but as a MemoryStream.
namespace Playground.Contracts{public interface IAWSS3Service{public Task<bool> UploadFileAsync(MemoryStream stream, string bucketName, string filePath);}}
Next step is to implement the UploadFileAsync function that uploads the file.
Implementation
The main purpose of this function is to create a TransferUtilityUploadRequest and use its UploadAsync function to upload the file to the S3 bucket.
But keep in mind that you have to update your appsettings.json to include the bucket name, file path and default region.
Another thing is a prerequisite which is to configure your AWS profile by using AWS CLI or create a security group for the instance which will have to the bucket because then you can just initialize an AWS client just like in the code below.
using Amazon;using Amazon.S3;using Amazon.S3.Transfer;using Microsoft.Extensions.Configuration;using Playground.Contracts;namespace Playground.Implementations{public class AWSS3Service : IAWSS3Service{private readonly IConfiguration _configuration;private readonly AmazonS3Client s3Client;private readonly TransferUtility fileTransferUtility;public AWSS3Service(IConfiguration configuration){_configuration = configuration;var region = _configuration["AWS:DefaultRegion"];s3Client = new AmazonS3Client(RegionEndpoint.GetBySystemName(region));fileTransferUtility = new TransferUtility(s3Client);}public async Task<bool> UploadFileAsync(MemoryStream stream, string bucketName, string filePath){TransferUtilityUploadRequest transferUtilityUploadRequest = new TransferUtilityUploadRequest{InputStream = stream,BucketName = bucketName,Key = filePath,};await fileTransferUtility.UploadAsync(transferUtilityUploadRequest);return true;}}}
After we add this service, we must register is in program.cs to inject it in the controller.
builder.Services.AddTransient<IAWSS3Service, AWSS3Service>();
All good! Now let's see how the API is going to receive the file and how is it going to convert it to MemoryStream.
Controller
Now that we have the AWS service injected, we can use it and pass the configured bucket information along with the file after converting it to MemorySream as follows.
using Microsoft.AspNetCore.Mvc;using Playground.Contracts;namespace HARDCODE.API.Controllers{[ApiController][Route("[controller]")]public class FileController : ControllerBase{private readonly IAWSS3Service _awsS3Service;private readonly IConfiguration _configuration;public FileController(IAWSS3Service awsS3Service, IConfiguration configuration){_awsS3Service = awsS3Service;_configuration = configuration;}[HttpPost][Route("upload-file-to-s3")]public async Task<string> UploadFileToS3(IFormFile file){var fileMemoryStream = new MemoryStream();file.CopyTo(fileMemoryStream);var filePath = _configuration["AWS:FilePath"] + file.FileName;var bucketName = _configuration["AWS:BucketName"];await _awsS3Service.UploadFileAsync(fileMemoryStream, bucketName, filePath);return filePath;}}}
Perfect! Now your API is all set to upload the desired bucket. But after getting the file path or persisting in some data source we need another API that allows us to download that file from the bucket. Well, I will show you how to do so in an upcoming post.
Comments
Post a Comment