Points clés à retenir
- Le téléversement des fichiers inclus dans la requête multipart de création d’Assembly ne peut pas reprendre ; toute interruption fait donc échouer l’Assembly entière.
- Le téléversement via tus permet à un client de poursuivre à partir de la position en octets déjà enregistrée par le serveur au lieu de recommencer.
- Créez en premier l’Assembly avec num_expected_upload_files, puis téléversez les fichiers à l’adresse tus_url qu’elle renvoie.
Un téléversement volumineux n’est pas une requête qui échoue occasionnellement. C’est un transfert qui sera interrompu, et la seule véritable décision est de savoir si, après une interruption, l’utilisateur devra transférer les octets restants ou la totalité des octets. Tout le reste de la conception découle de ce choix.
L’essentiel
- Dès que le nombre déclaré de fichiers est reçu, l’Assembly n’attend plus de téléversements supplémentaires. Comparez sa liste de téléversements aux fichiers que vous comptiez envoyer pour vérifier leur concordance.
- Les fichiers peuvent atteindre 200 GB, mais les téléversements doivent se terminer dans les huit heures suivant la création de l’Assembly par défaut ; le traitement a un délai distinct.
Deux modes de téléversement, dont un seul permet la reprise
Transloadit accepte les fichiers de deux manières, et leur différence ne se manifeste que lorsque la connexion est mauvaise. Les fichiers peuvent être joints à la requête POST multipart/form-data qui crée l’Assembly, une solution simple et adaptée à une photo de profil. Toute interruption de cette requête fait échouer le téléversement et l’Assembly avec lui, et le client ne peut pas reprendre le transfert : il doit tout renvoyer.
L’autre mode utilise tus, un protocole ouvert de téléversement avec reprise sur HTTP, dont des implémentations clientes existent dans la plupart des langages. Transloadit exploite un serveur tus, et un client qui utilise ce protocole peut se mettre en pause, perdre sa connexion et reprendre à partir du dernier octet dont le serveur a accusé réception. Pour tout fichier dont la taille se mesure en centaines de mégaoctets, cela fait la différence entre un téléversement qui finit par aboutir et un autre qui n’aboutit jamais.
Multipart
Une seule requête transporte les fichiers. Une interruption fait échouer à la fois le téléversement et l’Assembly.
tus
Un transfert distinct par fichier, qui peut reprendre à partir du dernier octet dont le serveur a accusé réception.
Déjà pris en charge pour vous
Le plugin Transloadit d’Uppy et le SDK Node officiel utilisent tus pour les téléversements de fichiers. Vérifiez individuellement si les autres SDK prennent en charge tus.
Déclarer le nombre de fichiers à venir
Un téléversement avec reprise inverse l’ordre habituel : l’Assembly est créée avant que le moindre octet ne soit disponible. La requête de création contient params comme d’habitude, ainsi qu’un champ num_expected_upload_files indiquant le nombre de fichiers qui suivront, mais aucun contenu de fichier. La réponse est un Assembly Status ordinaire, avec deux ajouts qui nous intéressent ici : tus_url pour la destination des téléversements, et le trio expected_tus_uploads, started_tus_uploads et finished_tus_uploads pour leur suivi.
L’Assembly reste dans l’état ASSEMBLY_UPLOADING jusqu’à la fin des téléversements attendus, même lorsque les fichiers arrivés tôt ont déjà été traités. Dès que le nombre déclaré de fichiers a été reçu, elle n’attend plus de fichiers supplémentaires. Les téléversements tardifs peuvent être rejetés ou ignorés selon l’état de l’Assembly. Définissez donc le nombre exact prévu et comparez la liste finale uploads aux fichiers que vous comptiez envoyer.
POST /assemblies HTTP/1.1
Host: api2.transloadit.com
Content-Type: multipart/form-data; boundary=---xyz
-----xyz
Content-Disposition: form-data; name="params"
{"auth":{"key":"YOUR_KEY"},
"template_id":"YOUR_TEMPLATE_ID"}
-----xyz
Content-Disposition: form-data;
name="num_expected_upload_files"
2
-----xyz--num_expected_upload_files
Définissez sa valeur sur le nombre exact de fichiers que le client enverra, et comptez les fichiers avant de créer l’Assembly.
tus_url
Le point de terminaison de téléversement de cette Assembly, renvoyé dans l’Assembly Status plutôt que codé en dur.
Comparer les fichiers reçus aux fichiers prévus
Comparez la liste des téléversements de l’Assembly aux fichiers prévus, au lieu de supposer qu’une exécution réussie prouve que tous les fichiers sont arrivés.
La reprise repose sur une position, pas sur une nouvelle tentative
Chaque téléversement commence par une requête POST vers tus_url qui crée une ressource au lieu d’envoyer des données. La requête contient trois métadonnées, assembly_url, filename et fieldname, et le serveur répond avec une URL de téléversement dans l’en-tête Location. Les octets sont ensuite envoyés à cette URL dans une ou plusieurs requêtes PATCH. Dès que la dernière est reçue, le fichier est transmis à l’Assembly sans appel supplémentaire.
La reprise utilise la même URL. Une requête HEAD renvoie un en-tête Upload-Offset indiquant le nombre d’octets effectivement détenus par le serveur, et le client reprend avec une requête PATCH à partir de cette position exacte. C’est pourquoi une nouvelle tentative et une reprise ne sont pas la même opération : une nouvelle tentative renvoie le fichier à partir de zéro, tandis qu’une reprise demande au serveur ce qu’il possède déjà et n’envoie que la différence.
HEAD /resumable/files/136058f2ef4d HTTP/1.1
Host: api2-freja.transloadit.com
Tus-Resumable: 1.0.0
HTTP/1.1 204 No Content
Upload-Offset: 3000
Upload-Length: 10000
PATCH /resumable/files/136058f2ef4d HTTP/1.1
Host: api2-freja.transloadit.com
Tus-Resumable: 1.0.0
Upload-Offset: 3000
Content-Length: 7000
Content-Type: application/offset+octet-streamCréer, puis transférer
Le premier POST établit l’URL de téléversement ; les requêtes PATCH transportent le contenu proprement dit.
Upload-Offset
Le serveur indique la quantité reçue, si bien que le client n’a jamais à deviner où reprendre.
Conserver l’URL de téléversement
La reprise après un rechargement de la page nécessite cette URL. Stockez-la donc de manière persistante au lieu de la conserver en mémoire.
Le transfert reprend, mais l’Assembly expire toujours
La possibilité de reprendre un transfert est souvent interprétée comme un délai de grâce illimité, ce qu’elle n’est pas. Par défaut, le téléversement est limité à huit heures à compter de la création de l’Assembly, et le traitement à huit heures à compter de la fin du téléversement. Une limite de traitement propre au Workspace peut modifier ce second délai. Une Assembly qui dépasse le délai qui lui est applicable renvoie ASSEMBLY_EXPIRED, et le téléversement partiel associé cesse d’être utile.
Ce point est particulièrement important pour les charges de travail qui nécessitent justement la reprise. Un utilisateur qui met un téléversement volumineux en pause pour la nuit retrouvera une Assembly qui n’existe plus. Le client doit donc détecter ce cas et en créer une nouvelle, au lieu de réessayer avec une URL qui ne fonctionne plus. Traiter l’expiration comme une issue attendue, plutôt que comme une erreur à journaliser, permet de gérer ce cas de reprise de manière réaliste.
Huit heures pour téléverser
Le délai court à compter de la création de l’Assembly, et non de la dernière progression du transfert.
Délai de traitement distinct
Le délai de traitement par défaut est de huit heures à compter de la fin du téléversement, indépendamment du délai de téléversement.
Prévoir un redémarrage
Détectez une Assembly expirée et créez-en une nouvelle au lieu de réessayer avec l’ancienne URL de téléversement.
Joindre les métadonnées nécessaires à chaque fichier
Au-delà des trois valeurs obligatoires, toute métadonnée supplémentaire envoyée avec un téléversement devient accessible sous forme d’Assembly Variable dans file.user_meta. Ainsi, une clé envoyée sous le nom owner se lit via ${file.user_meta.owner}. Il est utile de bien assimiler cette distinction dès le départ, car fields est partagé par tous les fichiers de l’Assembly, tandis que les métadonnées utilisateur appartiennent à un seul fichier. Un lot dans lequel chaque fichier nécessite son propre chemin de destination, propriétaire ou catégorie requiert ces métadonnées individuelles. Tenter de représenter ces informations dans des champs partagés aboutit à un Template incapable de distinguer les fichiers.
Pour déterminer les branches à suivre selon le contenu plutôt que selon les déclarations du client, privilégiez ${file.mime} et recherchez des correspondances avec des familles telles que image/* ou video/*. Un nom de fichier ou une catégorie fournis par le client sont des indices : les traiter comme des faits peut conduire à envoyer un exécutable dans une branche conçue pour des images. La catégorie générale ${file.type} existe également, mais la correspondance MIME est la plus précise des deux méthodes.
Les trois éléments requis
Chaque téléversement doit inclure assembly_url, filename et fieldname dans ses métadonnées tus.
Par fichier ou par Assembly
Les métadonnées utilisateur appartiennent à un seul fichier ; les champs sont partagés par tous les fichiers d’une même exécution.
Créer des branches selon le type MIME
Vérifiez la correspondance avec ${file.mime} plutôt que de vous fier à une extension ou à une catégorie fournie par le client.
Signer la requête lorsque le navigateur est le client
Lorsqu’un téléversement démarre dans un navigateur, les Assembly Instructions sont soumises depuis un environnement que vous ne contrôlez pas. Signature Authentication comble cette lacune : votre backend signe les paramètres avec l’Auth Secret, ajoute un horodatage auth.expires situé dans un futur proche et transmet le résultat au frontend. Si vous activez cette exigence dans les Paramètres du Workspace, l’API rejette toute requête non signée pour le compte.
L’intérêt est que votre serveur décide de ce qu’il accepte de signer. Il peut refuser les utilisateurs anonymes, restreindre le Template qu’une requête peut invoquer ou limiter les paramètres avant la signature, le tout avec une logique applicative ordinaire. L’Auth Secret ne quitte jamais le serveur, et une signature interceptée n’est valable que jusqu’à l’échéance fixée lors de son émission.
const uppy = new Uppy().use(Transloadit, {
waitForEncoding: true,
assemblyOptions: async () => {
// Your back end signs with the Auth Secret
const res = await fetch('/api/tl-signature', { method: 'POST' })
if (!res.ok) throw new Error('Unable to authorize the upload')
const { params, signature } = await res.json()
return { params, signature }
},
})Signer sur le serveur
L’Auth Secret reste sur le serveur et ne se retrouve jamais dans un bundle destiné au navigateur.
auth.expires
Un horodatage dans un avenir proche qui limite la durée d’utilisation d’une signature émise.
Exiger la signature
Les Paramètres du Workspace peuvent rejeter d’emblée toute requête non signée pour le compte.
Détails techniques à connaître
- L’Assembly est créée par une requête POST multipart contenant params et num_expected_upload_files, mais aucun contenu de fichier, et la réponse inclut tus_url, expected_tus_uploads, started_tus_uploads et finished_tus_uploads.
- Une Assembly reste dans l’état ASSEMBLY_UPLOADING jusqu’à la fin de chaque téléversement tus déclaré, même si certains fichiers qu’elle a déjà reçus ont été traités.
- Chaque téléversement tus commence par une requête POST vers tus_url contenant assembly_url, filename et fieldname comme métadonnées, et le serveur renvoie l’URL de téléversement dans l’en-tête Location.
- La reprise consiste en une requête HEAD vers cette URL de téléversement, dont la réponse indique le nombre d’octets reçus dans l’en-tête Upload-Offset, suivie d’une requête PATCH qui envoie le reste à partir de cette position exacte.
- Les métadonnées supplémentaires envoyées avec un téléversement deviennent une Assembly Variable sous file.user_meta, propre à chaque fichier, contrairement à fields, partagé par tous les fichiers d’une même Assembly.
- Par défaut, le téléversement est limité à huit heures à compter de la création, et le traitement à huit heures à compter de la fin du téléversement. Une limite de traitement propre au Workspace peut modifier cette seconde échéance ; le dépassement de l’une ou l’autre échéance renvoie ASSEMBLY_EXPIRED.
Une approche pratique
- 1
Créez l’Assembly en définissant num_expected_upload_files sur le nombre exact de fichiers que le client enverra.
- 2
Téléversez chaque fichier à l’adresse tus_url fournie dans l’Assembly Status avec un client tus plutôt qu’avec une simple requête POST.
- 3
Stockez l’URL de téléversement de manière persistante côté client pour permettre la reprise du transfert après un rechargement ou un plantage, au lieu de recommencer.
- 4
Signez la requête de création d’Assembly sur votre backend chaque fois que le navigateur est le client.
Quand Transloadit est utile
Utilisez Uppy avec le plugin Transloadit dans le navigateur, ou n’importe quel client tus ailleurs, et laissez /upload/handle recevoir les fichiers. Créez en premier l’Assembly avec num_expected_upload_files, puis envoyez chaque fichier à l’adresse tus_url renvoyée dans l’Assembly Status.
Périmètre architectural
La reprise permet de poursuivre un transfert interrompu, pas un transfert oublié. Par défaut, les téléversements doivent se terminer dans les huit heures suivant la création de l’Assembly, et le traitement dans les huit heures suivant la fin du téléversement. Une limite de traitement propre au Workspace peut modifier ce second délai. Après expiration, l’Assembly renvoie ASSEMBLY_EXPIRED et les octets déjà reçus ne sont plus utilisables.
Questions fréquentes
Dois-je implémenter le protocole tus moi-même ?
Généralement, non. Le plugin Transloadit d’Uppy et le SDK Node officiel utilisent tus pour le téléversement de fichiers. D’autres SDK peuvent ne pas intégrer tus ; vérifiez le SDK que vous utilisez avant de compter sur la reprise. L’implémentation directe du protocole concerne la création d’un SDK ou l’utilisation d’un langage pour lequel aucun SDK Transloadit adapté n’existe.
Pourquoi certains de mes fichiers ne sont-ils jamais apparus dans les résultats ?
Vérifiez si num_expected_upload_files correspondait au nombre de fichiers prévu. Dès que ce nombre de fichiers est reçu, l’Assembly n’attend plus de téléversements supplémentaires. Comparez sa liste uploads avec vos enregistrements de fichiers côté client, examinez les requêtes de téléversement ayant échoué et comptez les fichiers avant de créer l’Assembly suivante.
Que se passe-t-il si l’utilisateur ferme l’onglet pendant un téléversement ?
Le transfert peut reprendre tant que le client a conservé l’URL de téléversement et que l’Assembly n’a pas expiré. Stockez cette URL de manière persistante hors de la mémoire de la page, puis envoyez une requête HEAD au retour pour connaître la position en octets et reprendre à cette position.
Quelle taille maximale de fichier puis-je téléverser ?
Les fichiers jusqu’à 200 GB sont pris en charge, et des limites supérieures peuvent être convenues. En pratique, la contrainte est généralement le temps plutôt que la taille : par défaut, le téléversement dispose de huit heures à compter de la création de l’Assembly, un délai qu’une connexion lente peut épuiser avant la fin du transfert d’un très gros fichier.
Les informations propres à chaque fichier doivent-elles figurer dans les champs ou dans les métadonnées ?
Utilisez les métadonnées de téléversement tus lorsque la valeur concerne un seul fichier, car elle arrive sous forme d’Assembly Variable sous file.user_meta. Utilisez fields uniquement pour les valeurs partagées par tous les fichiers de l’Assembly, comme un identifiant client qui s’applique à l’ensemble du lot.