AWS NodeJS App 02 – Consulta DynamoDB

Antes de iniciar o desenvolvimento da nossa aplicação vamos instalar o pacote nodemon, que facilita o processo de desenvolvimento pois ele além de colocar nossa aplicação em execução ele monitora qualquer alteração no código fonte da aplicação e reinicia o servidor para que as modificações sejam refletidas. Mais detalhes em: https://www.npmjs.com/package/nodemon

Utilize o comando:

npm install -g nodemon

Para simplificar o processo de desenvolvimento, vamos utilizar a biblioteca DynamoDB Data Mapper para mapear nossos objetos de dados com os objetos recuperados e enviados para o DynamoDB.

npm install --save @aws/dynamodb-data-mapper @aws/dynamodb-data-mapper-annotations @aws-sdk/client-dynamodb-v2-node 

O próximo passo foi criar uma pasta chamada models dentro de nossa aplicação e dentro dela inserir a classe Product que servirá como classe modelo para troca de dados dentro do modelo MVC.

var {
  DataMapper, DynamoDbSchema, DynamoDbTable
} = require('@aws/dynamodb-data-mapper');
class Product{
    
}
Object.defineProperties(Product.prototype, {
    [DynamoDbTable]: {
        value: 'product'
    },
    [DynamoDbSchema]: {
        value: {
            id: {
                type: 'String',
                keyType: 'HASH'
            },
            description: {type: 'String'},
            name: {type: 'String'},
            price: {type: 'Number'}
        },
    },
});
module.exports = Product;

Agora crie uma nova pasta na aplicação chamada services, dentro desta pasta crie um programa chamado productservice.js, nesta classe vamos utilizar o SDK da AWS para connectar ao DynamoDB e realizar uma simples consulta do tipo scan e retornar os objetos encontrados.

var {
  DataMapper, DynamoDbSchema, DynamoDbTable
} = require('@aws/dynamodb-data-mapper');
var DynamoDB = require('aws-sdk/clients/dynamodb');

const client = new DynamoDB({region: 'us-east-2'});
const mapper = new DataMapper({client});
const Product = require("../models/product");

class ProductService{
   async getAll(){
        var list = [];
        var result = await mapper.scan(Product);
        for await (const item of result) {
            list.push(item);
        }
        return list;

   } 
}
module.exports = ProductService;

Agora vamos construir a lógica do controlador da interface view index. Para isso crie uma pasta no projeto com o nome controller e dentro dela crie um novo arquivo chamado indexcontroller.js Utilize o código de exemplo abaixo.

var ProductService = require("../services/productservice");
var productService = new ProductService();

class IndexController{
    async index(req,res,next){
        var listProduct  = await productService.getAll();
        //console.log(JSON.stringify(listProduct, null, 4));
        res.render('index2', { listProduct: listProduct });
    }
}
module.exports = IndexController;

Por fim devemos alterar o arquivo de rotas para que quando a página index for acessada, este controlador seja chamado contendo a lógica da apresentação dos produtos. Para isso dentro da pasta routes altere o código do arquivo index.js

var express = require('express');
var router = express.Router();

var IndexController = require("../controller/indexcontroller");
var indexController = new IndexController();

/* GET home page. */
router.get('/', function(req, res, next) {
    indexController.index(req,res,next);
});

module.exports = router;

Então podemos modificar o código da VIEW para apresentar os dados dos produtos. Dentro da pasta views procure pelo arquivo index2.hbs, dentro deste arquivo você vai encontrar duas vezes o tag: <article class=”card card-product”> deixe apenas o primeiro grupo de tags article com esta class card-product, e remova todo o segundo conjunto. Antes de iniciar o tag article utilize o comando {{#each listProduct}} da biblioteca Handlebars para indicar o início do bloco de repetição. No tag H4 utilize o comando {{this.name}} para que o nome do produto seja apresentado.

Agora no fim do conjunto de tags </article> utilize o comando {{/each}} do Handlebars para indicar o fim do bloco.

Execute a aplicação través do comando nodemon e acesse o endereço de preview, para se certificar que os dados são apresentados com sucesso.