Conclusiones clave
- Los archivos incluidos en la solicitud multipart de creación de la Assembly no pueden reanudarse, por lo que cualquier interrupción hace fallar toda la Assembly.
- Subir mediante el protocolo tus permite que un cliente continúe desde el desplazamiento de bytes que el servidor ya conserva, en lugar de comenzar de nuevo.
- Primero crea la Assembly con num_expected_upload_files y luego sube los archivos a la tus_url que devuelve.
Una subida grande no es una solicitud que falla ocasionalmente. Es una transferencia que se interrumpirá, y la única decisión real es si una interrupción le cuesta al usuario los bytes restantes o todos ellos. Todo lo demás en el diseño se deriva de esa elección.
Lo más importante
- Las subidas que exceden la cantidad declarada se descartan silenciosamente, por lo que un desfase de uno en esa cifra provoca la pérdida de archivos sin generar un error.
- Los archivos pueden tener hasta 200 GB, pero la Assembly vence de todos modos ocho horas después de su creación.
Distingue las dos rutas de subida: solo una se reanuda
Transloadit acepta archivos de dos maneras, y la diferencia entre ellas solo se manifiesta con una mala conexión. Los archivos pueden adjuntarse a la solicitud POST multipart/form-data que crea la Assembly, una opción sencilla y adecuada para una foto de perfil. Cualquier interrupción de esa solicitud hace fallar tanto la subida como la Assembly, y el cliente no tiene forma de continuar: solo puede enviarlo todo de nuevo.
La otra opción usa el protocolo tus, un protocolo abierto para subidas reanudables mediante HTTP, con implementaciones de cliente en la mayoría de los lenguajes. Transloadit ejecuta un servidor tus, y un cliente compatible con el protocolo puede pausar la transferencia, perder la conexión y retomarla desde el último byte confirmado por el servidor. Para cualquier archivo de cientos de megabytes, esa es la diferencia entre una subida que finalmente termina y otra que nunca lo hace.
Multipart
Una solicitud que transporta los archivos. Una interrupción hace fallar tanto la subida como la Assembly.
tus
Una transferencia independiente por archivo que puede continuar desde el último byte confirmado.
Ya resuelto para ti
Uppy y los SDK del back end usan el protocolo tus internamente, por lo que la mayoría de las integraciones obtiene esta capacidad sin trabajo adicional.
Declara cuántos archivos se recibirán
Una subida reanudable invierte el orden habitual: la Assembly se crea antes de que se envíe cualquier byte. La solicitud de creación incluye params como de costumbre, además de un campo num_expected_upload_files que indica cuántos archivos se enviarán después, y no contiene datos de ningún archivo. La respuesta es un Assembly Status convencional con dos adiciones relevantes: tus_url, que indica adónde se envían las subidas, y el trío expected_tus_uploads, started_tus_uploads y finished_tus_uploads, que permite seguirlas.
Esa cantidad declarada se aplica con más rigor de lo que parece al principio. La Assembly permanece en ASSEMBLY_UPLOADING hasta que hayan terminado todas las subidas esperadas, incluso cuando los archivos que llegaron antes ya se hayan procesado. Las subidas que exceden la cantidad declarada se descartan sin generar un error, lo que convierte una cifra incorrecta en uno de los fallos más difíciles de detectar: la Assembly finaliza correctamente y simplemente falta un archivo en los resultados.
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
Configúralo con la cantidad exacta de archivos que enviará el cliente y cuenta los archivos antes de crear la Assembly.
tus_url
El endpoint de subida de esta Assembly, devuelto en el Assembly Status en lugar de estar definido directamente en el código.
Los archivos adicionales desaparecen
Todo lo que exceda la cantidad declarada se descarta silenciosamente, por lo que conviene validar esa cifra.
Reanuda desde un desplazamiento, no mediante un reintento
Cada subida comienza con una solicitud POST a tus_url que crea un recurso en lugar de enviar datos. La solicitud incluye tres metadatos, assembly_url, filename y fieldname, y el servidor responde con una URL de subida en el encabezado Location. Después, los bytes se transfieren a esa URL mediante una o más solicitudes PATCH y, cuando llega la última, el archivo se incorpora a la Assembly sin ninguna llamada adicional.
La recuperación utiliza la misma URL. Una solicitud HEAD devuelve un encabezado Upload-Offset con la cantidad de bytes que el servidor realmente tiene, y el cliente reanuda la transferencia mediante una solicitud PATCH que comienza exactamente en ese desplazamiento. Por eso, reintentar y reanudar no son la misma operación: un reintento vuelve a enviar el archivo desde cero, mientras que una reanudación consulta al servidor qué parte ya tiene y envía solo la diferencia.
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-streamCrear y luego transferir
La primera solicitud POST establece la URL de subida; las solicitudes PATCH transfieren el contenido real.
Upload-Offset
El servidor indica cuánto recibió, por lo que el cliente nunca tiene que adivinar desde dónde continuar.
Conservar la URL de subida
Para reanudar después de volver a cargar una página se necesita esa URL, así que guárdala de forma persistente en lugar de conservarla en memoria.
Reanuda la transferencia, pero ten en cuenta que la Assembly aún vence
La capacidad de reanudación suele interpretarse como un periodo de gracia ilimitado, pero no lo es. La Assembly se creó al principio y su reloj ya está en marcha: la subida está limitada a ocho horas; el procesamiento, a ocho horas adicionales; y ambos en conjunto, a dieciséis horas desde la creación. Una Assembly que supera esos límites devuelve ASSEMBLY_EXPIRED, y la subida parcial asociada deja de ser útil.
Esto importa sobre todo para las cargas de trabajo que de entrada necesitan capacidad de reanudación. Un usuario que pausa durante la noche una subida de gran tamaño volverá a una Assembly que ya no existe, así que el cliente debe detectar ese caso y crear una nueva en lugar de reintentar con una URL inactiva. Tratar el vencimiento como un resultado esperado, en vez de como un error que debe registrarse, mantiene clara la lógica de esa ruta de recuperación.
Ocho horas para subir
Se mide desde la creación de la Assembly, no desde la última vez que avanzó la transferencia.
Límite de dieciséis horas
La subida y el procesamiento combinados no pueden superar las dieciséis horas desde la creación.
Planificar un reinicio
Detecta una Assembly vencida y crea una nueva en lugar de reintentar con la URL de la subida anterior.
Adjunta los metadatos que necesita cada archivo
Además de los tres valores obligatorios, cualquier metadato adicional enviado con una subida queda disponible como una Assembly Variable en file.user_meta; por eso, una clave enviada como owner se lee como ${file.user_meta.owner}. Conviene asimilar pronto esta diferencia, porque fields se comparte entre todos los archivos de la Assembly, mientras que los metadatos del usuario pertenecen a un solo archivo. Si cada archivo de un lote necesita su propia ruta de destino, propietario o categoría, debes usar estos últimos. Si intentas expresarlo mediante campos compartidos, terminarás con un Template que no puede distinguir los archivos.
Para crear ramificaciones según el contenido y no según lo que declaró el cliente, utiliza preferentemente ${file.mime} y busca coincidencias con familias como image/* o video/*. Un nombre de archivo o una categoría proporcionados por el cliente son solo indicios; tratarlos como hechos puede hacer que un ejecutable termine en una ruta que daba por supuesto que recibiría imágenes. La categoría general ${file.type} también existe, pero la coincidencia por MIME es la más exacta de las dos.
Tres valores obligatorios
Cada subida necesita assembly_url, filename y fieldname en sus metadatos del protocolo tus.
Por archivo o por Assembly
Los metadatos del usuario pertenecen a un solo archivo; los campos se comparten entre todos los archivos de la misma ejecución.
Crear ramificaciones según MIME
Busca coincidencias con ${file.mime} en lugar de confiar en una extensión o una categoría proporcionada por el cliente.
Firma la solicitud cuando el navegador sea el cliente
Una subida que comienza en un navegador implica que las Assembly Instructions se envían desde un entorno que no controlas. Signature Authentication cierra esa brecha: tu back end firma los params con el Auth Secret, añade una marca de tiempo auth.expires para un momento próximo y entrega el resultado al front end. Activar este requisito en la Configuración del Workspace hace que la API rechace cualquier solicitud sin firma para la cuenta.
La ventaja es que tu servidor decide qué está dispuesto a firmar. Puede rechazar a usuarios anónimos, limitar el Template que una solicitud puede invocar o restringir los parámetros antes de firmarlos, todo mediante la lógica habitual de la aplicación. El Auth Secret nunca sale del back end, y una firma interceptada solo es válida hasta el vencimiento con el que se emitió.
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')
const { params, signature } = await res.json()
return { params, signature }
},
})Firmar en el servidor
El Auth Secret permanece en el back end y nunca llega a un paquete del navegador.
auth.expires
Una marca de tiempo próxima que limita durante cuánto tiempo puede utilizarse una firma emitida.
Exigir la firma
La Configuración del Workspace puede rechazar categóricamente, sin excepciones, todas las solicitudes sin firma para la cuenta.
Detalles técnicos que conviene conocer
- La Assembly se crea mediante una solicitud POST multipart que incluye params y num_expected_upload_files, pero no contenido de archivos, y la respuesta incluye tus_url, expected_tus_uploads, started_tus_uploads y finished_tus_uploads.
- Una Assembly permanece en el estado ASSEMBLY_UPLOADING hasta que finalizan todas las subidas declaradas mediante el protocolo tus, incluso cuando algunos de los archivos que ya recibió se hayan procesado.
- Cada subida mediante el protocolo tus comienza con una solicitud POST a tus_url que incluye assembly_url, filename y fieldname como metadatos, y el servidor responde con la URL de subida en el encabezado Location.
- La reanudación consiste en una solicitud HEAD a esa URL de subida, que informa la cantidad de bytes recibidos en el encabezado Upload-Offset, seguida de una solicitud PATCH que envía el resto exactamente desde ese desplazamiento.
- Los metadatos adicionales enviados con una subida se convierten en una Assembly Variable en file.user_meta, que corresponde a cada archivo, a diferencia de fields, que se comparte entre todos los archivos de la misma Assembly.
- La subida está limitada a ocho horas y el procesamiento a otras ocho, con un máximo de dieciséis horas desde la creación; después, la Assembly devuelve ASSEMBLY_EXPIRED.
Un enfoque práctico
- 1
Crea la Assembly con num_expected_upload_files configurado con la cantidad exacta de archivos que enviará el cliente.
- 2
Sube cada archivo a la tus_url del Assembly Status con un cliente tus, en lugar de usar una solicitud POST convencional.
- 3
Guarda de forma persistente la URL de subida en el cliente para poder reanudarla después de recargar la página o de un fallo, en lugar de reiniciarla.
- 4
Firma la solicitud de creación de la Assembly en tu back end siempre que el navegador sea el cliente.
Cuándo resulta útil Transloadit
Usa Uppy con el plugin de Transloadit en el navegador, o cualquier cliente tus en otros entornos, y deja que /upload/handle reciba los archivos. Primero crea la Assembly con num_expected_upload_files y luego envía cada archivo a la tus_url devuelta en el Assembly Status.
Límite de la arquitectura
La capacidad de reanudación recupera una transferencia interrumpida, no una olvidada. Las subidas deben finalizar dentro de las ocho horas posteriores a la creación de la Assembly, y el procesamiento dispone de otras ocho horas, con un límite total de dieciséis horas desde la creación. Después, la Assembly devuelve ASSEMBLY_EXPIRED y los bytes ya recibidos dejan de ser utilizables.
Preguntas frecuentes
¿Tengo que implementar el protocolo tus por mi cuenta?
Por lo general, no. Uppy y los SDK de back end usan el protocolo tus de forma predeterminada, por lo que una integración normal ya obtiene subidas reanudables. Implementar el protocolo directamente sirve para crear un SDK o usar un lenguaje para el que no existe un SDK de Transloadit.
¿Por qué algunos de mis archivos nunca aparecieron en los resultados?
La causa probable es que el valor de num_expected_upload_files sea menor que la cantidad de archivos realmente enviados. Las subidas que exceden la cantidad declarada se descartan silenciosamente, por lo que la Assembly finaliza correctamente, pero faltan archivos. Cuenta los archivos antes de crear la Assembly.
¿Qué ocurre si el usuario cierra la pestaña durante una subida?
La transferencia puede reanudarse siempre que el cliente haya conservado la URL de subida y la Assembly no haya vencido. Guarda esa URL fuera de la memoria de la página y, cuando regreses, envía una solicitud HEAD para conocer el desplazamiento y continuar desde allí.
¿Qué tamaño máximo puede tener un archivo que suba?
Se admiten archivos de hasta 200 GB y pueden acordarse límites superiores. En la práctica, la restricción suele ser el tiempo, no el tamaño: la subida dispone de ocho horas desde la creación de la Assembly, y una conexión lenta puede agotarlas antes de que termine un archivo muy grande.
¿La información de cada archivo debe ir en los campos o en los metadatos?
Usa los metadatos de subida del protocolo tus cuando el valor pertenezca a un solo archivo, ya que llega como una Assembly Variable en file.user_meta. Usa fields únicamente para valores compartidos por todos los archivos de la Assembly, como un identificador de cliente que se aplica a todo el lote.