Chuyển tới nội dung chính

riverbase_file

riverbase_fileExtensions · v0.2.0

Media management over OpenDAL: filesystem, S3 or HTTP storage plus metadata.

cargo add riverbase_file --git https://github.com/riverbase-io/riverbase --features aws-s3
  • postgresdefault
  • fsdefault
  • aws-s3
  • http

riverbase_file stores files on any OpenDAL backend and keeps their metadata in Postgres. It handles hashing, optional compression, and links between files and the domain resources that own them.

Configure storage​

[riverbase.media]
protocol = "s3" # fs | s3 | http
fskey = "default" # name of the default filesystem
root_path = "media/" # object-key prefix inside the storage root

[riverbase.media.params] # backend-specific settings
bucket = "acme-media"
region = "ap-southeast-1"
endpoint = "https://s3.ap-southeast-1.amazonaws.com"
# access keys from env: RIVERBASE_MEDIA_ACCESS_KEY_ID / RIVERBASE_MEDIA_SECRET_ACCESS_KEY

For local development, use protocol = "fs" with fs_root = "./var/media". Environment overrides (RIVERBASE_MEDIA_PROTOCOL, …_FS_ROOT, …_FSKEY, …_ROOT_PATH, …_BUCKET, …_REGION, …_ENDPOINT, …) win over the file.

Use it​

use std::sync::Arc;
use riverbase_file::{
establish_media_dbpool, MediaManager, OpenDalMediaManager, PostgresMediaMetadataStore, PutMediaRequest,
};

let pool = establish_media_dbpool(&db_url).await?;
let media = OpenDalMediaManager::new(Arc::new(PostgresMediaMetadataStore::new(pool)))
.with_default_fskey("default");

let entry = media
.put(PutMediaRequest {
filename: "invoice.pdf".into(),
content: bytes,
filemime: Some("application/pdf".into()),
fskey: None, // the default filesystem
compress: None,
resource: Some("invoice".into()),
resource_id: Some(invoice_id),
})
.await?;

let data = media.get(&entry.domain.id).await?;

MediaManager​

MethodPurpose
register_filesystem(FilesystemConfig)Add a named backend at runtime
put(PutMediaRequest)Store bytes and metadata; returns a MediaEntry
get(id) / stream(id, chunk_size)Read the whole file, or in chunks
get_metadata(id) / exists(id)Metadata lookups
copy(id, dest_fskey)Copy to another filesystem
delete(id)Remove bytes and metadata
list_files(MediaQuery)List by owning resource / resource_id, with paging

A MediaEntry records filename, filehash, filemime, length, fskey, fspath, the compression method, the owning resource, and optional CDN fields (cdn_url, cdn_exp). Files are laid out in hash-based folders, so no directory grows unbounded.

Uploads over HTTP​

Expose uploads through a custom route (see Custom endpoints). The multipart size limit is request_upload_max_bytes (default 20 MiB). Going over it fails with MED-086.