Cloud Agnostic - Storing & serving files
Cloud agnostic series
- Depending on a colour
- Depending on a colour Pt. 2 - Needs, Possibilities and Limitations
- Cloud Agnostic - introducing the AheadDockerized .NET Solution
- Cloud Agnostic - Storing & serving files
Let us start with a relatively simple, ubiquitous but necessary service: Storage of files. In ahead these are needed for attachments, images, videos and the like.
After investigating a bit, it appears that the safest bet here is to use something that is Amazon S3-compatible. AWS, by being first here, essentially set the standard for cloud storage, and many companies will offer such “S3-compatible” storage for you to use. Here’s an example from Switzerland.
Granted, using Azure Blob Storage is straightforward from a developer perspective: Having a local “emulator”
is as easy as saying npm install azurite
. I could imagine that there might be a similar
offering for S3-compatible storage, but considering that I have an Aspire-project available,
setting up a container is also a straightforward activity. The company min.io offers an “object store”
that can be run at hyperscale as well as locally on a Docker container. The relevant code is hosted at github
Defining such a container as a resource in Aspire looks like this:
Gist not showing up? Most likely you're using Chrome. Reload the page to see the gist.
People who know docker containers probably recognize the different settings that are being set:
- 2 environment variables that define the admin user with which we can log in at min.io’s dashboard (port 9090)
- port bindings
- volume bindings
- startup arguments
Aspire gives you a fluent API to define settings on the different kind of resources. Interesting are also the
two variables minioUser
, minioPassword
which are defined further up:
During development, these values come from a “Parameters” section in appSettings.Development.json
.
Once I start the solution by running the AppHost
Aspire project, I can access the min.io dashboard by
clicking the provided link in the Aspire dashboard:
In the dashboard I can log in with the provided user / password values and create an access key:
These will be required when accessing the service.
The relevant Nuget to access the service is simply called minio, and provides an up-to-date library to talk to min.io (and by extension S3 compatible) services.
The Ahead.Dockerized
solution introduces a blob storage interface with some example API that is linked to UI in order to be able to use it:
⬇️ This is the implementation of the upload – it takes an IFormFile
instance and stores it in the service.
I found it amusing that, just coming from an Aspire frontend, I ended up using a fluent interface again.
While they’re kind of nice to read, getting there is not always as obvious as one cannot see from the API what is
mandatory vs what is not, hence it is sometimes something of a trial and error to get the right incantation.
Another thing I wanted to check out is the signed url functionality - Links to files in ahead are usually written
like api/files/{fileId}
- the server then redirects to a signed url, which lets you see the file for a limited amount of time:
This is how to get the necessary url through the min.io API:
In this case, the link expires after one hour.
All in all, blob storage is, as expected, one of the easier things to treat in a cloud-agnostic way.