Arquitectura antigua:
La arquitectura que seguíamos para hacer la subida de documentación a S3 era la siguiente:
-
El cliente web (navegadores, móviles, etc) a través de un formulario añadía los documentos que queria subir a la aplicación.
-
La aplicación (API) transformaba los documentos al formato que correspondiera y los subía a Amazon S3.
-
Amazon S3 le decía a la API que los documentos habían sido guardados y los añadía a la BBDD.
-
La API le informaba al cliente web que los ficheros se habían guardado.
-
El cliente web le informaba al usuario si los ficheros se habían subido de manera correcta, o por el contrarío, le informaba de que algo había ido mal.
Análisis de la situación
Al transformar los ficheros a través de la API, que está tuviera que subir los documentos a Amazon S3 e informar al cliente web de cómo había ido la subida de la documentación, hacía que la API necesitará consumir muchos recursos, además de hacer que el usuario tuviera que esperar a que la API le contestará.
Por esta razón decidimos que lo mejor era hacer la subida a través de URL prefirmadas o preformadas.
Estás URL prefirmadas o preformadas son unas URLs que tienen un tiempo de expiración y te permiten realizar un tipo de solicitud autenticada directamente a Amazon S3 a través de parámetros, en lugar de tener que utilizar encabezados de autenticación.
Con estas URLs lo que conseguimos es habilitar al cliente web (navegador, móvil, etc) para poder realizar una petición a datos de Amazon S3 que son privados, y gracias a la fecha de expiración, nos permite tener un mayor control sobre el acceso que se da al contenido de Amazon S3.
https://nombre-bucket.s3.eu-west-2.amazonaws.com/nombre-del-documento.extension?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=API-KEY-PUBLICA-AMAZON-S3/20190605/eu-west-2/s3/aws4_request&X-Amz-Date =20190605T194312Z&X-Amz-SignedHeaders=host&X-Amz-Expires=5&X-Amz-Signature=2084e800fbba78b2df3fe43010ce199314646c7523d016c7f8f2d034b0f49ef0
- Primera parte, https://nombre-bucket.s3.eu-west-2.amazonaws.com
-
Hace referencia al bucket de S3 donde se va a guardar el fichero y al lugar donde se está ejecutando eu-west-2.
- Segunda parte, /nombre-del-documento.extension
-
Hace referencia al nombre con el que se va a guardar el fichero en nuestro bucket, no tiene porque ser el mismo nombre que el nombre del fichero.
- Tercera parte, ?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential =API-KEY-PUBLICA-AMAZON-S3/20190605/eu-west-2/s3/aws4_request&X-Amz-Date=20190605T194312Z&X-Amz-SignedHeaders=host
-
Son las credenciales para poder subirlo a S3, como por ejemplo, la key pública, el lugar de donde es el bucket, la fecha, etc.
- Cuarta parte, &X-Amz-Expires=5&X-Amz-Signature=2084e800fb...
-
Hace referencia al tiempo de expiración de la URL prefirmada, a partir de la cual, dejará de funcionar la URL prefirmada y la petición que llevaba asociada.
La nueva arquitectura
La nueva arquitectura que tenemos una vez añadidas las URLs prefirmadas para la subida de documentación a Amazon S3 es:
-
El cliente web (navegadores, móviles, etc) a través de un formulario añade los documentos que quiere subir a la aplicación.
-
La aplicación (API) recoge el número de documentos que el usuario quiere subir y su nombre y le pide a Amazon S3 que cree una URL prefirmada por cada documento.
-
Amazon S3 le devuelve a la API una URL prefirmada para realizar una petición por cada fichero que se quiere subir.
-
La API le devuelve al cliente web un JSON con el nombre del documento y la URL prefirmada que tiene asignada.
-
El cliente web transforma el documento al formato deseado para realizar la petición a Amazon S3 y realiza una petición por cada documento para subirlo.
-
Amazon S3 nos devuelve una respuesta de sí todo ha ido bien o de si ha fallado algo.
-
El cliente web guarda la respuesta junto a los datos del documento que a subido y envía una petición a la API para que está lo guarde en la BBDD.
-
La API guarda la información que le envía el cliente web en la BBDD.
Conclusión
Como podemos observar, hemos pasado de realizar en la API la transformación de los documentos, la subida de los documentos a Amazon S3, guardar la información en la BBDD y responder al cliente, a simplemente, pedir unas URLs a Amazon S3, dárselas al cliente web y guardar los datos en la BBDD, lo que supone liberar a la API de mucho trabajo y al cliente web no tener que esperar a que la API le conteste para saber si ha ido bien la subida de la documentación o ha fallado algo.