rpc_dart_blob 1.0.1
rpc_dart_blob: ^1.0.1 copied to clipboard
Streamed blob storage contract and adapters for rpc_dart (binary/object storage alongside rpc_dart_data).
rpc_dart_blob #
Contract and adapters for streamed blob storage over rpc_dart. Think of it as the binary twin of rpc_dart_data: optimized for chunked uploads/downloads, checksums, and content types, without forcing base64 inside JSON payloads.
Quick start #
Server #
final storage = SqliteBlobStorageAdapter.file(
'blobs.sqlite',
readChunkBytes: 256 * 1024, // stream read size
);
final server = BlobServiceFactory.createServer(
transport: transport, // any IRpcTransport
storage: storage,
maxChunkBytes: 256 * 1024, // reject larger uploads
);
await server.start();
Client #
final client = BlobServiceFactory.createClient(
transport: transport,
uploadChunkBytes: 256 * 1024,
);
// Upload stream (chunked automatically).
await client.putBytes(
collection: 'photos',
id: 'p1', // optional; generated if absent
bytes: file.openRead(),
length: await file.length(),
contentType: 'image/jpeg',
checksum: '<sha256-of-file>',
checksumAlgorithm: ChecksumAlgorithm.sha256,
attachChunkChecksums: true, // optional per-chunk validation
);
// Range download with offsets reported on first frame.
final frames = await client.get('photos', 'p1', rangeStart: 0, rangeEnd: 1024).toList();
// Metadata only.
final head = await client.head('photos', 'p1');
// List without metadata (faster); set includeMetadata: true to fetch it.
final list = await client.list('photos', limit: 10, includeMetadata: false);
// Delete with optimistic version (optional).
await client.delete('photos', 'p1', expectedVersion: head.descriptor?.version);
In-memory setup (tests/dev) #
final env = await BlobServiceFactory.inMemory(
uploadChunkBytes: 128 * 1024,
maxChunkBytes: 256 * 1024,
);
final client = env.client;
S3/MinIO adapter #
final storage = S3BlobStorageAdapter.connect(
bucket: 'blobs',
endPoint: 'minio.local', // or s3.amazonaws.com
port: 9000,
accessKey: '<access>',
secretKey: '<secret>',
useSSL: false,
prefix: 'rpc/', // optional
);
final server = BlobServiceFactory.createServer(
transport: transport,
storage: storage,
);
Descriptors returned from S3 include a short-lived presigned download URL (downloadUrl).
Goals #
- Separate contract for blobs (
BlobService) sorpc_dart_datastays focused on JSON records. - Stream-first API (client-stream upload, server-stream download) with optimistic versioning.
- Pluggable storage adapters (SQLite for dev/tests, S3/MinIO for object storage; bucket must exist).
- Export/import-friendly framing (header + binary chunks) without loading whole files in memory.
Layout #
lib/src/models.dart— descriptors, chunk frames, list/delete/head requests.lib/src/adapters— storage adapter interface for concrete backends.lib/src/rpc— contract, caller/responder wiring, service interface (client-stream upload, server-stream download; chunks are base64-framed for now).
Status #
Includes SqliteBlobStorageAdapter for local/dev storage (payloads kept in BLOB columns with optimistic versioning) and S3BlobStorageAdapter for S3-compatible backends (AWS, MinIO, Ceph) storing blobs as <prefix><collection>/<id> with metadata-based versioning. BlobService provides a default server implementation on top of any IBlobStorageAdapter. The API is intentionally small to evolve toward zero-copy binary framing (replace base64 chunks with transport-native binary when ready).