Modelo CRUD para el manejo de objetos implementado con Systems Manager Parameter Store, Bucket S3, Api-Gateway, Serverless-Framework, Lambda, NodeJs, aws-sdk-v3, entre otros. Los servicios de aws se implementan en local. El código del proyecto y la documentación de este (menos doc técnica), ha sido desarrollado/a en inglés.
Ver
- 1.0) Descripción del Proyecto.
- 1.1) Ejecución del Proyecto.
- 1.2) Configuración del proyecto desde cero
- 1.3) Tecnologías.
1.0) Descripción 🔝
Ver
- Esta app está dividida en varias funcionalidades/componentes. El primer componente o capa de conexión (/bucket) es la interacción con aws-sdk y con el bucket. Se modulariza de forma tal qué tenemos archivos .js para la creación de clientes s3, lectura de bucket, escritura de bucket, etc. Luego para la capa de aplicación (/helpers) tenemos validaciones de encabezados, cuerpo de solicitudes, formatos de fechas, autenticación, etc. Seguidamente la capa controlador/vista (/controllers) está definida por las operaciones CRUD posibles en cada una de las lambdas definidas.
- La imagen de la arquitectura de aws empleada describe el flujo de funcionamiento de la app de forma general. Cualquier petición hacia el bucket parte desde un cliente (Postman, servidor, etc).
Paso 0
: Dicha solicitud es recibida por el api-gateway y solamente se validará si es que dentro de los encabezados de dicha solicitud se encuentra la x-api-key correcta.Pasos 1A, 1B, etc
: Todos estos pasos corresponden a un endpoint con su recurso especifico. Por ej. para uploadObject (1A) es http://localhost:4000/dev/upload-object ....revisar dichos endpoints en sección endpoints. Cada lambda realiza comprobación de x-api-key y Bearer token, entre otros.Pasos 2
: Las lambdas realizan las validaciones de las ssm correspondientes con el System Manager Paramater Store.. validan token, valores para el bucket s3, etc.Pasos 3
: Las lambdas realizan las solicitudes y operaciones necesarias contra el bucket s3 (lectura, actualización, eliminación e inserción de objetos).Aclaraciones
: Se emula dicho funcionamiento dentro de la misma red y en entorno local con los plugins de serverless correspondientes.
1.1) Ejecución del Proyecto 🔝
Ver
- Una vez creado un entorno de trabajo a través de algún ide, clonamos el proyecto
git clone https://github.com/andresWeitzel/CRUD_Bucket_S3_AWS
- Nos posicionamos sobre el proyecto
cd 'projectName'
- Instalamos la última versión LTS de Nodejs(v18)
- Instalamos Serverless Framework de forma global si es que aún no lo hemos realizado
npm install -g serverless
- Verificamos la versión de Serverless instalada
sls -v
- Instalamos todos los paquetes necesarios
npm i
- Las variables ssm utilizadas en el proyecto se mantienen para simplificar el proceso de configuración del mismo. Es recomendado agregar el archivo correspondiente (serverless_ssm.yml) al .gitignore.
- El siguiente script configurado en el package.json del proyecto es el encargado de
- Levantar serverless-offline (serverless-offline)
"scripts": {
"serverless-offline": "sls offline start",
"start": "npm run serverless-offline"
},
- Ejecutamos la app desde terminal.
npm start
- Si se presenta algún mensaje indicando qué el puerto 4000 ya está en uso, podemos terminar todos los procesos dependientes y volver a ejecutar la app
npx kill-port 4000
npm start
1.2) Configuración del proyecto desde cero 🔝
Ver
- Creamos un entorno de trabajo a través de algún ide, luego de crear una carpeta nos posicionamos sobre la misma
cd 'projectName'
- Instalamos la última versión LTS de Nodejs(v18)
- Instalamos Serverless Framework de forma global si es que aún no lo hemos realizado
npm install -g serverless
- Verificamos la versión de Serverless instalada
sls -v
- Inicializamos un template de serverles
serverless create --template aws-nodejs
- Inicializamos un proyecto npm
npm init -y
- Instalamos S3 local
npm install serverless-s3-local --save-dev
- Instalamos el Cliente s3
npm install @aws-sdk/client-s3
- Instalamos serverless offline
npm i serverless-offline --save-dev
- Instalamos serverless ssm
npm i serverless-offline-ssm --save-dev
- Las variables ssm utilizadas en el proyecto se mantienen para simplificar el proceso de configuración del mismo. Es recomendado agregar el archivo correspondiente (serverless_ssm.yml) al .gitignore.
- El siguiente script configurado en el package.json del proyecto es el encargado de
- Levantar serverless-offline (serverless-offline)
"scripts": {
"serverless-offline": "sls offline start",
"start": "npm run serverless-offline"
},
- Ejecutamos la app desde terminal.
npm start
- Si se presenta algún mensaje indicando qué el puerto 4000 ya está en uso, podemos terminar todos los procesos dependientes y volver a ejecutar la app
npx kill-port 4000
npm start
1.3) Tecnologías 🔝
Ver
| Tecnologías | Versión | Finalidad |
| ------------- | ------------- | ------------- |
| SDK | 4.3.2 | Inyección Automática de Módulos para Lambdas |
| Serverless Framework Core v3 | 3.23.0 | Core Servicios AWS |
| Systems Manager Parameter Store (SSM) | 3.0 | Manejo de Variables de Entorno |
| Amazon Api Gateway | 2.0 | Gestor, Autenticación, Control y Procesamiento de la Api |
| Amazon S3 | 3.0 | Contenedor de Objetos |
| NodeJS | 14.18.1 | Librería JS |
| VSC | 1.72.2 | IDE |
| Postman | 10.11 | Cliente Http |
| CMD | 10 | Símbolo del Sistema para linea de comandos |
| Git | 2.29.1 | Control de Versiones |
| Plugin | Descripción |
| ------------- | ------------- |
| Serverless Plugin | Librerías para la Definición Modular |
| serverless-offline | Este complemento sin servidor emula AWS λ y API Gateway en entorno local |
| serverless-offline-ssm | busca variables de entorno que cumplen los parámetros de SSM en el momento de la compilación y las sustituye desde un archivo |
| serverless-s3-local | complemento sin servidor para ejecutar clones de S3 en local
| Extensión |
| ------------- |
| Prettier - Code formatter |
| YAML - Autoformatter .yml (alt+shift+f) |
2.0) Endpoints y recursos 🔝
Ver
| Variable | Initial value | Current value |
| ------------- | ------------- | ------------- |
| base_url | http://localhost:4000 | http://localhost:4000 |
| x-api-key | f98d8cd98h73s204e3456998ecl9427j | f98d8cd98h73s204e3456998ecl9427j |
| bearer_token | Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c | Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c |
curl --location 'http://localhost:4000/dev/upload-object' \
--header 'x-api-key: f98d8cd98h73s204e3456998ecl9427j' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' \
--header 'Content-Type: application/json' \
--data '{
"type":"image",
"format":"png",
"description":"5000 × 3061 png",
"url":"https://www.bing.com/images/search?view=detailV2&ccid=Tf4BFI68&id=D66EF5BFB7DA0A645A70240C32CB8664E8F8BF09&thid=OIP.Tf4BFI6846neirVSebC0vAHaEi&mediaurl=https%3a%2f%2flogos-download.com%2fwp-content%2fuploads%2f2016%2f09%2fNode_logo_NodeJS.png&cdnurl=https%3a%2f%2fth.bing.com%2fth%2fid%2fR.4dfe01148ebce3a9de8ab55279b0b4bc%3frik%3dCb%252f46GSGyzIMJA%26pid%3dImgRaw%26r%3d0&exph=3061&expw=5000&q=jpg+nodejs&simid=608055434302923247&FORM=IRPRST&ck=2FF3D39CAEF945F20B996CF6042F88A6&selectedIndex=1&ajaxhist=0&ajaxserp=0"
}'
{
"message": {
"type": "image",
"format": "png",
"description": "5000 × 3061 png",
"url": "https://www.bing.com/images/search?view=detailV2&ccid=Tf4BFI68&id=D66EF5BFB7DA0A645A70240C32CB8664E8F8BF09&thid=OIP.Tf4BFI6846neirVSebC0vAHaEi&mediaurl=https%3a%2f%2flogos-download.com%2fwp-content%2fuploads%2f2016%2f09%2fNode_logo_NodeJS.png&cdnurl=https%3a%2f%2fth.bing.com%2fth%2fid%2fR.4dfe01148ebce3a9de8ab55279b0b4bc%3frik%3dCb%252f46GSGyzIMJA%26pid%3dImgRaw%26r%3d0&exph=3061&expw=5000&q=jpg+nodejs&simid=608055434302923247&FORM=IRPRST&ck=2FF3D39CAEF945F20B996CF6042F88A6&selectedIndex=1&ajaxhist=0&ajaxserp=0",
"uuid": 104851112
}
}
curl --location 'http://localhost:4000/dev/get-object/103053674' \
--header 'x-api-key: f98d8cd98h73s204e3456998ecl9427j' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' \
--header 'Content-Type: application/json' \
--data ''
{
"message": {
"type": "image",
"format": "jpg",
"description": "1000 × 1261 png",
"url": "https://www.bing.com/images/search?view=detailV2&ccid=Tf4BFI68&id=D66EF5BFB7DA0A645A70240C32CB8664E8F8BF09&thid=OIP.Tf4BFI6846neirVSebC0vAHaEi&mediaurl=https%3a%2f%2flogos-download.com%2fwp-content%2fuploads%2f2016%2f09%2fNode_logo_NodeJS.png&cdnurl=https%3a%2f%2fth.bing.com%2fth%2fid%2fR.4dfe01148ebce3a9de8ab55279b0b4bc%3frik%3dCb%252f46GSGyzIMJA%26pid%3dImgRaw%26r%3d0&exph=3061&expw=5000&q=jpg+nodejs&simid=608055434302923247&FORM=IRPRST&ck=2FF3D39CAEF945F20B996CF6042F88A6&selectedIndex=1&ajaxhist=0&ajaxserp=0",
"uuid": 103053674
}
}
curl --location --request PUT 'http://localhost:4000/dev/edit-object/104851112' \
--header 'x-api-key: f98d8cd98h73s204e3456998ecl9427j' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' \
--header 'Content-Type: application/json' \
--data '{
"type":"image",
"format":"jpg",
"description":"1200 × 1201 png",
"url":"https://www.bing.com/images/search?view=detailV2&ccid=Tf4BFI68&id=D66EF5BFB7DA0A645A70240C32CB8664E8F8BF09&thid=OIP.Tf4BFI6846neirVSebC0vAHaEi& mediaurl=https%3a%2f%2flogos-download.com%2fwp-content%2fuploads%2f2016%2f09%2fNode_logo_NodeJS.png&cdnurl=https%3a%2f%2fth.bing.com%2fth%2fid%2fR.4dfe01148ebce3a9de8ab55279b0b4bc%3frik%3dCb%252f46GSGyzIMJA%26pid%3dImgRaw%26r%3d0&exph=3061&expw=5000&q=jpg+nodejs&simid=608055434302923247&FORM=IRPRST&ck=2FF3D39CAEF945F20B996CF6042F88A6&selectedIndex=1&ajaxhist=0&ajaxserp=0"
}'
{
"message": {
"type": "image",
"format": "jpg",
"description": "1200 × 1201 png",
"url": "https://www.bing.com/images/search?view=detailV2&ccid=Tf4BFI68&id=D66EF5BFB7DA0A645A70240C32CB8664E8F8BF09&thid=OIP.Tf4BFI6846neirVSebC0vAHaEi& mediaurl=https%3a%2f%2flogos-download.com%2fwp-content%2fuploads%2f2016%2f09%2fNode_logo_NodeJS.png&cdnurl=https%3a%2f%2fth.bing.com%2fth%2fid%2fR.4dfe01148ebce3a9de8ab55279b0b4bc%3frik%3dCb%252f46GSGyzIMJA%26pid%3dImgRaw%26r%3d0&exph=3061&expw=5000&q=jpg+nodejs&simid=608055434302923247&FORM=IRPRST&ck=2FF3D39CAEF945F20B996CF6042F88A6&selectedIndex=1&ajaxhist=0&ajaxserp=0",
"uuid": 104851112
}
}
curl --location --request DELETE 'http://localhost:4000/dev/delete-object/104851112' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' \
--header 'x-api-key: f98d8cd98h73s204e3456998ecl9427j' \
--header 'Content-Type: application/json'
{
"message": "Removed object with uuid 104851112 successfully."
}