Archiviazione e file
Panoramica
Sezione intitolata “Panoramica”Il modulo client.storage fornisce metodi per la gestione dei file — caricamento, download, elenco ed eliminazione. Funziona sia con disco locale sia con backend di archiviazione compatibili con S3, a seconda della configurazione del server.
Tutti i metodi di archiviazione utilizzano il trasporto condiviso, quindi i token di autenticazione vengono iniettati automaticamente.
Caricare un file
Sezione intitolata “Caricare un file”Usa putObject() per caricare un file. Accetta un oggetto File o Blob insieme a una chiave di archiviazione e metadati opzionali:
const result = await client.storage.putObject({ file: fileObject, // File or Blob key: "products/images/camera.jpg", // Storage path (optional) bucket: "uploads", // Bucket name (optional) public: false, // Store public (permanent token-less URL) — optional, default false metadata: { // Custom metadata (optional) description: "Product photo", uploadedBy: "user-123" }});
// result: { key: string; bucket: string; storageUrl: string }Un file oltre 8 MiB sale attraverso l’endpoint
riprendibile (TUS) del server, 8 MiB per richiesta, invece che come un’unica richiesta multipart che il server
analizza per intero — così un caricamento grande costa al server un chunk di memoria, non da tre
a cinque volte il file. Un chunk che fallisce lungo la strada viene inviato di nuovo da dove
il server era arrivato. Il risultato, l’oggetto memorizzato e i controlli del server
sono gli stessi in entrambi i casi. Quando l’endpoint riprendibile non può accettare il file (un
server più vecchio, o più istanze che non condividono i caricamenti), il file va come un unico
POST /api/storage/upload, e lo stesso vale per ogni file successivo di quel client. Vedi
Caricamenti riprendibili (TUS).
Da un campo file
Sezione intitolata “Da un campo file”const input = document.querySelector<HTMLInputElement>("#file-input");const file = input?.files?.[0];
if (file) { const result = await client.storage.putObject({ file, key: `avatars/${userId}/${file.name}` }); console.log("Uploaded to:", result.key);}Ottenere un URL firmato
Sezione intitolata “Ottenere un URL firmato”Recupera un URL di download e i metadati di un file archiviato:
const { url, metadata, fileNotFound } = await client.storage.getSignedUrl( "products/images/camera.jpg");
if (url) { console.log("Download URL:", url); console.log("Content type:", metadata?.contentType);} else { console.log("File not found");}Con un bucket specifico:
const { url } = await client.storage.getSignedUrl( "camera.jpg", "product-images" // bucket);L’SDK memorizza nella cache gli URL firmati per evitare chiamate ridondanti al server, fino alla scadenza
del token di download di ciascuno. Le ricerche fatte insieme — una pagina di anteprime
che chiama getSignedUrl() nello stesso tick — vanno al server come un solo
POST /api/storage/metadata ogni 100 file, che il rate limiter conta come un
decimo delle richieste che sostituisce; un file che un chiamante non può leggere fa fallire
solo quella chiamata. La cache appartiene alla credenziale che l’ha richiesta: quando il token
di accesso cambia — una disconnessione, un altro utente che accede, un refresh — riparte da zero, così a un
utente non viene mai consegnato un URL generato per un altro.
URL privati vs. pubblici
Sezione intitolata “URL privati vs. pubblici”- I file privati ottengono un URL con un token di download a breve durata, limitato al percorso (
?token=…, 5 minuti salvo che il server impostiSTORAGE_DOWNLOAD_TOKEN_TTL, che la 0.23 non legge) — mai il tuo token di accesso. Poiché scade, non conservare un URL privato; memorizza il percorso del file e richiamagetSignedUrl()al momento del rendering. - I file pubblici (archiviati sotto il prefisso
public/— impostastorage: { public: true }sulla proprietà, o passapublic: trueaputObject) ottengono un URL stabile, senza token, permanente e memorizzabile nella CDN, senza andata e ritorno al server. Sono sicuri da memorizzare in un database e da collegare direttamente.
File dentro un testo
Sezione intitolata “File dentro un testo”Un testo che incorpora un file — le immagini in un campo markdown — non può
contenere nemmeno un URL privato, quindi contiene invece un riferimento di
storage: rebase-storage:posts/cover.png, con ?storageId=media quando il
file si trova in una sorgente nominata. È ciò che scrive l’editor markdown del
pannello di amministrazione per un’immagine caricata. Scambia i riferimenti con
URL quando esegui il rendering del testo:
import { resolveStorageReferences } from "@rebasepro/client";
const post = await client.data.collection("posts").findById("post-1");const body = await resolveStorageReferences(String(post?.body ?? ""), client);// `body` is the same markdown, each reference replaced by a fresh URL.Ogni oggetto viene firmato una volta per chiamata, dalla propria sorgente, così
un’immagine privata continua a funzionare indipendentemente da quanto tempo fa
è stata caricata. Un riferimento che nomina un oggetto che non esiste più viene
lasciato com’è. storageReference(key, storageId?) ne costruisce uno, per un
testo che scrivi tu stesso.
Un testo salvato prima che i riferimenti esistessero contiene l’URL di download
di un file privato, …/storage/file/posts/cover.png?token=…, il cui token è scaduto pochi minuti
dopo la scrittura. resolveStorageReferences rinnova anche questi: il token
nomina ancora l’oggetto, quindi l’URL viene sostituito da uno nuovo. Per memorizzare
invece dei riferimenti, riscrivi il testo una volta con
storageReferencesForDownloadUrls(text), che lascia ogni altro URL
com’è.
Scaricare un file
Sezione intitolata “Scaricare un file”Recupera un file come oggetto File:
const file = await client.storage.getObject("products/images/camera.jpg");
if (file) { console.log("File name:", file.name); console.log("File type:", file.type); console.log("File size:", file.size);
// Create a download link const url = URL.createObjectURL(file); window.open(url);} else { console.log("File not found");}Con un bucket specifico:
const file = await client.storage.getObject("camera.jpg", "product-images");Eliminare un file
Sezione intitolata “Eliminare un file”await client.storage.deleteObject("products/images/camera.jpg");
// With bucketawait client.storage.deleteObject("camera.jpg", "product-images");L’eliminazione di un file inesistente non genera un errore.
Elencare i file
Sezione intitolata “Elencare i file”Elenca i file per prefisso, con paginazione opzionale:
const result = await client.storage.listObjects("products/images/", { bucket: "uploads", maxResults: 50, pageToken: undefined // for pagination});
for (const item of result.items) { console.log(item.fullPath, item.name, item.size, item.updated, item.contentType);}
// Paginateif (result.nextPageToken) { const nextPage = await client.storage.listObjects("products/images/", { pageToken: result.nextPageToken });}Ogni elemento porta la sua size in byte e updated (un
timestamp ISO 8601) su storage locale, S3 e GCS, e il suo contentType su storage locale
e GCS — abbastanza per mostrare una cartella senza un getSignedUrl() per file. Un elenco
S3 non ha il content type; le cartelle (result.prefixes) non portano nessuno dei
tre.
Formati delle chiavi di archiviazione
Sezione intitolata “Formati delle chiavi di archiviazione”L’SDK gestisce in modo trasparente i prefissi delle chiavi di archiviazione. Puoi passare le chiavi con o senza il prefisso di protocollo:
// All equivalent — the SDK strips the prefix internallyawait client.storage.getSignedUrl("local://products/image.jpg");await client.storage.getSignedUrl("s3://products/image.jpg");await client.storage.getSignedUrl("products/image.jpg");Riferimento dell’API
Sezione intitolata “Riferimento dell’API”| Metodo | Descrizione | Restituisce |
|---|---|---|
putObject({ file, key?, bucket?, metadata? }) |
Caricare un file | UploadFileResult |
getSignedUrl(key, bucket?) |
Ottenere l’URL di download + metadati | DownloadConfig |
getObject(key, bucket?) |
Scaricare come oggetto File |
File | null |
deleteObject(key, bucket?) |
Eliminare un file | void |
listObjects(prefix, options?) |
Elencare i file per prefisso | StorageListResult |
Prossimi passi
Sezione intitolata “Prossimi passi”- Configurazione dell’archiviazione — Configurare S3 o l’archiviazione locale sul server
- Interrogare i dati — Operazioni CRUD e query builder
- Autenticazione — Accesso e gestione delle sessioni