Files for .NET apps, stored where you choose
Resourcefull stores and serves files of any type and size from infrastructure you run yourself: the SQL Server or PostgreSQL database you already have, or a directory on your own disks. Upload, download, list and version them through one client API. When you move to the cloud, change one line to keep the bytes in Amazon S3, another S3-compatible store or Azure Blob Storage instead.
builder.Services.AddResourcefull(options => options
.UseSqlServer(connectionString)
.UseVersioning(maxVersions: 10));
// Streams the body into storage, at any size.
app.MapPut("/files/{container}/{**name}",
(string container, string name,
HttpRequest request, IResourceServiceClient files) =>
files.GetContainerClient(container)
.UploadFromRequestAsync(name, request));
// Sends the file with ETags and range requests (4.0).
app.MapGet("/files/{container}/{**name}",
(string container, string name,
IResourceServiceClient files) =>
Results.Resource(
files.GetContainerClient(container),
name));
Everything files need, in one library
The parts every application ends up writing around file storage, built once, tested against every provider, and documented for people who aren't storage specialists.
Any size, flat memory
Uploads and downloads stream, so a 5 GB video costs the same memory as a thumbnail. Every file's length and SHA-256 hash are measured as it's stored.
Versions you can restore
Keep the last few versions of every file, list them, and bring an older one back. Pruning keeps storage in check by itself.
Safe under load
Many servers can write the same names at once. Conditional writes let exactly one of several editors save, without locks of your own.
Made for ASP.NET Core
Serve downloads with ETags, 304s and range requests 4.0, accept uploads with preconditions, and turn errors into the right status codes.
Quotas and rules 4.0
Limit each container's file sizes, total size and file count, allow only certain file types, or make a container read-only.
Links that expire 4.0
Let someone without an account download one file, until a time you choose, with a signed link your application creates.
Files that clean up after themselves 4.0
Give uploads an expiry and they're deleted when it passes, with a hook that lets you record every deletion for auditing.
Backups in one call 4.0
Export a whole container, every version, to a zip file, and import it into another store with its IDs and history intact.
Observable from day one 4.0
OpenTelemetry spans and metrics for every operation, and health checks that tell your orchestrator when storage is down.
Find your way
The documentation is grouped by what you're trying to do.
Working with files
- Containers and names
- Uploading and downloading
- Versioning and copying
Managing storage
Running in production
Testing and extending
Reference
Your storage, your choice
Your code talks to one API. The provider decides where the bytes go, and you can change it without touching the rest of your application.
SQL Server
Resourcefull.SqlServer for production: streamed in chunks, transactional, with migrations and
retries built in.
PostgreSQL
Resourcefull.PostgreSql for production on PostgreSQL: the same chunked streaming, transactions,
migrations and retries.
SQLite
Resourcefull.Sqlite for a single database file, with no server to run: desktop and edge applications,
a single server, and tests.
File system
Resourcefull.FileSystem for a directory on a local disk or a file share: nothing else to run, and
every feature the other providers have.
S3-compatible storage
Resourcefull.S3 for Amazon S3 or another S3-compatible store, when you move to the cloud: change one
line and keep your code.
Azure Blob Storage
Resourcefull.AzureBlob for Azure Blob Storage, the same way: one line to switch, the same API.
In memory
Resourcefull.InMemory for tests and local development: the same behavior, nothing to set up.
Your own
Implement one interface to store files anywhere else, and check it with the same contract tests the built-in providers pass.