Table of Contents

📂 Working with S3 Files

This step adds file storage to the Potato.Examples solution using the Potato.Files abstraction and the S3 implementation.


1. 📦 Install Packages

From the Infrastructure project:

cd Potato.Examples.Infrastructure

dotnet add package Potato.Files

dotnet add package Potato.Files.S3

2. ⚙️ Configure appsettings.json

"PotatoS3Files": {
  "ServiceUrl": "http://localhost:9000",
  "AccessKey": "admin",
  "SecretKey": "potato123",
  "BucketName": "potato-dev",
  "UseHttp": true
}

3. 🛠 Register Services

In Program.cs of your API project:

builder.Services.AddPotatoS3Files(builder.Configuration);

Ensure the bucket exists on startup:

app.Lifetime.ApplicationStarted.Register(async () =>
{
    await app.EnsureS3BucketExists();
});

4. 🚀 Minimal API Endpoints

app.MapPut("/upload", async (IFormFile file, PotatoFiles files) =>
{
    await files.Upload(Guid.NewGuid(), "files", file).GetOrThrow();
    return Results.Ok();
}).DisableAntiforgery();

app.MapGet("/list", async (string directory, PotatoFiles files) =>
{
    return Results.Ok(await files.ListFiles(directory).GetOrThrow());
});

app.MapGet("/get", async (string path, PotatoFiles files) =>
{
    var item = await files.Get(path).GetOrThrow();
    return Results.Stream(item.Content, item.ContentType, Path.GetFileName(item.FilePath));
});

app.MapDelete("/delete", async (string path, PotatoFiles files) =>
{
    await files.Delete(path).GetOrThrow();
    return Results.Ok();
});

5. 🐳 Start MinIO

Add the following service to your docker-compose.yml:

minio:
  image: minio/minio
  command: server /data --console-address ":9001"
  ports:
    - "9000:9000"
    - "9001:9001"
  environment:
    MINIO_ROOT_USER: admin
    MINIO_ROOT_PASSWORD: potato123
  volumes:
    - minio_data:/data

Run:

docker compose up -d

✅ Summary

You can now upload, list, retrieve and delete files via S3 while still using Potato's file abstraction.

➡️ Next: Vector Search with Qdrant