lunes, 3 de abril de 2017

Api Gateway , multipart/form-data parser. Multi File Uploader.

El siguiente es un video tutorial que muestra los pasos a seguir para poder crear un Api en Amazon ApiGateway que procesa el POST enviado por un formulario que trae archivos (texto o binario).

El formulario envía datos usando: "multipart/form-data". El contenido "multipart" implica que todos los archivos seleccionados desde el formulario vendrán uno junto al otro separados por un elemento llamado "boundary" (que es creado y enviado también por el cliente Http en sus headers).

Para poder procesar el contenido multipart/form-data es necesario de una herramienta que he creado y publicado en los paquetes NPM, a continuación:

https://www.npmjs.com/package/parse-multipart

La necesidad que me llevó a crear el paquete es la propia naturaleza de Api Gateway y la falta de disponibilidad o exceso de complicación de otras herramientas existentes, estas ultimas mejor orientadas a servir esquemas tradicionales, es decir, sus autores las han creado para automatizar lo mas que se pueda el proceso desde el lado del servidor para el payload enviado. Este exceso de automatización es bueno para esos casos normales donde se usan servidores dedicados a servir el request, pero para el caso de Api Gateway son relativamente complicados de implementar o requiren de dependencias. El paquete "parse-multipart" en cambio (enlace arriba) es simple, es una sola maquina de estado finito capaz de leer el contenido crudo del payload y entregar un array con los archivos obtenidos de el.

En el video a continuación describo cinco pasos claros (descritos en el video), el codigo al que se hace referencia en el video lo dejo acá:

form.html, un formulario que corre en algun servidor http y que envia el POST al api gateway.

<html>
<h1>
ApiGateway: File Uploading Example</h1>
<form action="https://voceeedzwf.execute-api.us-west-2.amazonaws.com/test/uploader" enctype="multipart/form-data" method="POST">

<input multiple="" name="your-files" type="file" />

<input type="submit" value="Submit" />
</form>
</html>


package.json, usado para poder importar el paquete "parse-multipart"

{
  "name": "lambda",
  "version": "1.0.0",
  "description": "sample tutorial",
  "main": "index.js",
  "dependencies" : { 
   "parse-multipart" : "*" 
  },
  "author": "Cristian Salazar  (https://plus.google.com/+ChristianSalazar)",
  "license": "ISC"
}

index.js El código de la función lambda.

// see also: https://www.npmjs.com/package/parse-multipart
var multipart = require("parse-multipart");

// "exports.handler" must match the entrypoint defined in the lambda Config.
exports.handler = function(event,context,callback){
 var bodyBuffer = new Buffer(event['body-json'].toString(),'base64');
 var boundary = multipart.getBoundary(event.params.header['content-type']);

 var parts = multipart.Parse(bodyBuffer,boundary);
 
 callback(null,{ result : 'SUCCESS' , files : parts });
}


A continuación el video:




















3 comentarios:

  1. Hola, está interesante tu video del multipart/form-data. La verdad estoy tratando de ver si con tu herramienta que subiste a npm se pueden parsear archivos y datos de formulario. En el ejemplo solo vienen archivos. Estoy tratando de ejecutar en un solo lambda la creación de un producto con su imagen, y también tengo una función para importar varios productos con sus imágenes en un solo POST. Saludos desde Mexico!

    ResponderEliminar
    Respuestas
    1. que bueno, me alegro que te pueda servir. en github tienes algunas actualizaciones y/o casos en que otras personas han tenido algunos problemas (resueltos). Si, te presenta un fallo puedes abrir un ticket en github. Saludos desde Chile :)

      Eliminar
    2. hola roberto, agrego una 2nda respuesta a tu pregunta. Si puedes enviar foto+data, debido a la naturaleza del proceso "multipart", el cual admite que en un POST vengan varias "partes" (de ahi el termino "multipart"), cada parte con su información, puede ser: parte 1, la foto, parte 2 el paypload del formulario de la foto1 y asi sucesivamente para tener varias fotos+texto en el mismo POST. Te recalco si que, si algo no anda bien entonces subas un nuevo issue (en ingles) en el sitio de github, incorporando un caso de pruebas (un payload de pruebas) de modo de que yo pueda reparar rapidamente sin adivinar. :)

      Eliminar