IBM Cloudant persistindo dados de um Web Service construído em Node-RED

O IBM Cloudant é um banco de dados no-SQL oferecido na solução de nuvem chamada IBM Cloud. Esse tipo de banco dados é muito utilizado em aplicações que tem como requisito arquitetural possuir a habilidade de ser escalável caso haja um aumento na carga de uso da aplicação. Neste tutorial iremos utilizaro IBM Cloudant como método de persistência de dados enviados por um web service construído da ferramenta Node-RED. O Node-RED é um projeto open source, patrocinado pela IBM, com o objetivo de construir uma ferramenta que permita o desenvolvimento de aplicações complexas utilizando apenas blocos.

O primeiro passo é criar no IBM Cloud um serviço chamado Node-RED Starter. Para isso acesse o menu catálogo, e no campo de busca selecione a opção Node-RED Starter. Uma vez concluído o processo de criação do serviço e de instalação do Node-RED, acesse o serviço através da URL sugerida pelo wizard.

Como o objetivo desse tutorial é construir um Web Server, vamos utilizar o padrão REST para construir nossa solução, portanto toda vez que uma URL for acessada, o serviço receberá dados pela URL ou pelo corpo da requisição através de um objeto JSON. Para construir a lógica do web service, precisamos de dois blocos básicos do Node-RED o http INPUT que é responsável por receber as requisições HTTP e o http response que é responsável por retornar para o cliente o resultado.

Funcionalidade Add

A primeira funcionalidade que vamos construir é a responsável por adicionar um novo registro em nosso banco de dados Cloudant. O primeiro passo é colocar um par de nós HTTP, input e output. Em seguida clique duas vezes no nó http input. Selecione o método POST e digite no campo da URL /doc/add, então confirme no botão Done.

O próximo passo é buscar no menu lateral, digitando cloud, o nó do Cloudant será apresentado. Selecione a opção do nó Cloudant e arraste para o meio da janela do Flow1. Em seguida clique duas vezes no nó Cloudant, conforme a imagem a seguir, no campo Database digite o nome do banco de dados que será criado no Cloudant, a sugestão é dbapp, no campo operation selecione a opção insert e marque a opção “Only store msg.payload object” desta forma o nó irá aceitar apenas dados que forem enviados no formato JSON dentro da propriedade payload da mensagem recebida pelo nó http input.

Para concluir, faça a conexão do nó http input com o nó cloudant e outra conexão do nó http input com o http response output. Então clique no botão Deploy para atualizar a aplicação.

Para testar nosso webservice vamos utilizar a aplicação postman, que foi configurar conforme a imagem a seguir. Modificamos o método para POST, e no campo da URL digitamos o mesmo endereço do serviço do Node-RED mas com o final /doc/add. Configuramos o body da requisição para o tipo RAW e selecionamos o mimetype JSON. Dentro da caixa de texto criamos um objeto JSON com duas propriedades nome e cidade. Por fim clicamos no botão Send.

Se agora utilizamos o Cloudant Dashboard dentro do IBM Cloud, vamos observar que um novo banco foi criado chamado dbapp, e clicando neste banco um novo documento foi criado contendo os dados que foram enviados para o web service.

Funcionalidade consultar documentos

A próxima funcionalidade será uma rota no web service para listar todo o conteúdo de documentos do banco de dados. Para isso, conforme a figura abaixo, adicione mais um nó http input e um novo nó cloudant, mas selecione a opção que possui entrada e saída de fluxo.

Clique duas vezes no novo nó http input para configurá-lo, mantenha a opção do método GET, e digite na URL o endereço /doc/list.

Em seguida clique duas vezes sobre o novo nó cloudant, e digite no campo database o nome do banco de dados dbapp e na opção de search by selecione a opção all documents. Confirme no botão Done.

Para concluir, conecte o novo nó http input ao novo nó cloudant, e esse conecte ao nó http response output que já existe no flow1. Clique no botão Deploy.

O teste desta nova rota no web service pode ser feito utilizando o navegador ou utilizar o Postman, basta selecionar o metodo GET, digitar a URL termiminada por /doc/list e clicar no botão Send, na caixa de resposta será apresentado os documentos salvos no banco de dados.

Funcionalidade consultar documentos por ID

Todo documento salvo no Cloudant recebe um atributo de identificação _id que é único. Para realizar a consulta de um objeto por esse identificador que é gerado automaticamente, devemos inserir mais um nó http input, um nó function que permitirá escrever código JavaScript e um novo nó Cloudant com dois terminais.

O primeiro passo é configurar o nó http input clicando duas vezes sobre ele, selecione o método GET e digite na URL /doc.

O próximo passo é configurar a function, seu objetivo é alterar a organização da mensagem JSON que foi recebida pelo nó http input, para copiar o parâmetro doc que será passado pela URL, para dentro da propriedade payload do objeto msg. Após digitar o código confirme no botão Done.

O último nó que precisa ser configurado é o nó do cloudant, para isso clique duas vezes e no campo database digite dbapp e no campo search by selecione a opção _id.

Para concluir ligue o nó http input ao nó function, em seguida este nó ao cloudant e por fim o cloudant ao http response output. Confirme no botão deploy.

Para testar, vamos utilizar novamente o Postman, inserindo a URL da aplicação /doc e incluindo o parâmetro ?doc= ao número do ID do documento, que pode ser obtido pela consulta /doc/list.

Funcionalidade consultar documentos por uma propriedade

Esta é a consulta mais complexa, mas mais importante da aplicação, vamos imaginar que queremos fazer uma consulta pelo campo nome do documento, para isso precisamos primeiro acessar o Dashboard do banco Cloudant para criar um índice de consulta, e em seguida podemos executar a consulta do Node-RED. Para isso acesse o Dashboard do banco Cloudant e acesse seu banco de dados dentro dele, então na opção design documents, clique no icone + e selecione a opção New Search Index.

No campo save to design document selecionamos a opção New Document, no campo ao lado o nome do documento que será consultadocumento, e no campo index name o nome do índice que será indicenome. Agora precisamos escrever nossa função de indexação, essa função que realiza a busca no banco de dados e será chamada quando esse documento que representa o índice de busca for solicitado. Nossa função recebe um parâmetro doc que representa os dados da consulta. Primeiro chamamos a função index para tentar buscar os documentos no banco caso nenhum campo for enviado para a consulta, desta forma será considerado que foi passado para a busca o _id gerado pelo banco automaticamente. Caso objeto doc possua a propriedade nome, a função index será utilizada para fazer a busca pelo campo “nome”, considerando o valor passado em doc.nome.

Ainda na mesma tela, precisamos configurar como a consulta será executada em cada campo, para isso selecionamos a opção Multiple pois temos busca por _id e pelo nome, em seguida clicamos no botão Add Field e digitamos nome, mantendo o Analizer como Standard. Para concluir confirmamos no botão Create Document and Build Index.

Quando o novo índice for criado, a próxima tela será apresentada onde podemos fazer o testes da busca, digitando nome:valor conseguimos executar a consulta e verificar seu funcionamento.

Retornando para o Node-RED, vamos construir o fluxo para a consulta para isso, insira os seguintes nós no flow1: http input, function e um nó cloudant.

Clique duas vezes sobre o nó http, selecione o método GET e informe no campo URL /doc/list/prop.

O próximo passo é configurar nossa function, seu objetivo será buscar o valor de consulta recebido pelo nó http input e configurá-lo dentro da propriedade payload.query. Para isso clique duas vezes sobre o nó function, digite o código conforme exemplo abaixo.

O mais importante passo é configurar nosso nó cloudant, clique duas vezes sobre ele, e informe o nome do banco de dados, e no campo search by selecione a opção search index, no campo abaixo informe o nome do documento que criou nosso índice consultadocumento e do lado o nome do índice que é indicenome. Confirme no botão Done.

O último passo é conectar nossos nós conforme a figura a seguir e clicar no botão Deploy.

Para testar nossa consulta, utilizamos novamente o Postman, selecionando o método GET, e digitando na URL o final /doc/list/prop?query= onde nossa query será procurar por nome:walter.

Funcionalidade alterar documentos

Agora que já criamos algumas opções de consulta, vamos concluir a aplicação construindo os métodos PUT para alterar um documento e DELETE para remover um documento.

Vamos precisar dos seguintes nós para construir a opção de alterar um documento: http input, function e um nó cloudant apenas como entrada.

O primeiro passo é configurar nosso nó http, selecionando o método PUT e digitando na URL /doc/update

O próximo passo é configurar nossa function, conforme o código a seguir: estamos copiando a propriedade payload.document para dentro da propriedade payload diretamente e em seguida removendo a propriedade document.

Por fim vamos configurar nosso nó cloudant, basicamente precisamos apenas preencher o campo com o nome do banco de dados. Apesar da opção operation esta selecionada como insert, caso esse nó receba um objeto com a propriedade _id idêntica a um objeto que já exista no banco, seu valor será atualizado. IMPORTANTE: SELECIONE A OPÇÃO Only store msg.payload object

Para concluir, devemos fazer as conexões dos nós, observe que do nó function temos duas saídas, uma vai para o nó http output e outro vai para o nó cloudant.

Para testar a opção de alterar, vamos utilizar o Postman, selecionando o método PUT, digitando na URL /doc/update e selecionando a opção body -> raw -> JSON e no campo abaixo inserindo o código JSON de um objeto com a propriedade document e esse com as propriedades _id e _rev igual ao do documento já existente no banco e passando o novo estado do objeto no banco. Observe que além do nome ter sido alterado a propriedade cidade foi apagada do documento.

Funcionalidade remover documentos

O último método que precisa ser implementado é a remoção de um objeto do banco de dados. Para isso vamos incluir os três últimos nós que são http input, function e cloudant.

O nó http deve ser configurado com o método DELETE e com a URL /doc/remove.

O nó function deverá ser configurado com o código conforme o exemplo abaixo:

E o nó cloudant deve ser configurado com o nome do banco de dados e a operação igual a remove. Desta forma quando esse nó receber pela propriedade payload os atributos _id e _rev de um documento, ele será removido do banco de dados.

Para concluir devemos conectar os nós conforme a imagem a seguir, mas lembrando que o nó function deverá ser conectado ao nó http response output e ao nó cloudant. Lembre-se de clicar no botão deploy para publicar a lógica.

Para testar nosso novo método de remoção configuramos o Postman para o método delete, informamos a URL e configuramos o body para o tipo RAW -> JSON onde informamos um objeto contendo o _id e o _rev de um documento existente no banco de dados para a sua exclusão.

Código final da aplicação

[{"id":"8a63752d.c93578","type":"function","z":"8038d84.dd63128","name":"","func":"msg.payload = msg.payload.doc;\nreturn msg;","outputs":1,"noerr":0,"x":250,"y":300,"wires":[["e9c7ddcc.4f4f1"]]},{"id":"1c7db3f6.dbe16c","type":"http in","z":"8038d84.dd63128","name":"","url":"/doc/add","method":"post","upload":false,"swaggerDoc":"","x":150,"y":80,"wires":[["bf8c53ad.7ed04","30282359.3e066c"]]},{"id":"30282359.3e066c","type":"http response","z":"8038d84.dd63128","name":"","statusCode":"","headers":{},"x":470,"y":120,"wires":[]},{"id":"bf8c53ad.7ed04","type":"cloudant out","z":"8038d84.dd63128","name":"","cloudant":"","database":"dbapp","service":"noderedwaltercoan-cloudantNoSQLDB","payonly":true,"operation":"insert","x":350,"y":40,"wires":[]},{"id":"b34bc51b.f1d258","type":"http in","z":"8038d84.dd63128","name":"","url":"/doc/list","method":"get","upload":false,"swaggerDoc":"","x":150,"y":160,"wires":[["23853a1c.f04b26"]]},{"id":"23853a1c.f04b26","type":"cloudant in","z":"8038d84.dd63128","name":"","cloudant":"","database":"dbapp","service":"noderedwaltercoan-cloudantNoSQLDB","search":"_all_","design":"","index":"","x":310,"y":200,"wires":[["30282359.3e066c"]]},{"id":"e9c7ddcc.4f4f1","type":"cloudant in","z":"8038d84.dd63128","name":"","cloudant":"","database":"dbapp","service":"noderedwaltercoan-cloudantNoSQLDB","search":"_id_","design":"","index":"","x":410,"y":280,"wires":[["30282359.3e066c"]]},{"id":"4fb832de.84afdc","type":"http in","z":"8038d84.dd63128","name":"","url":"/doc","method":"get","upload":false,"swaggerDoc":"","x":120,"y":260,"wires":[["8a63752d.c93578"]]},{"id":"45e9cdbb.4ba4b4","type":"http in","z":"8038d84.dd63128","name":"","url":"/doc/list/prop","method":"get","upload":false,"swaggerDoc":"","x":130,"y":380,"wires":[["f8f14015.c9e"]]},{"id":"f8f14015.c9e","type":"function","z":"8038d84.dd63128","name":"","func":"msg.payload.query = msg.payload.query + "*";\nmsg.payload.limit = 100;\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":440,"wires":[["9f5094b0.6b64d8"]]},{"id":"9f5094b0.6b64d8","type":"cloudant in","z":"8038d84.dd63128","name":"","cloudant":"","database":"dbapp","service":"noderedwaltercoan-cloudantNoSQLDB","search":"_idx_","design":"consultadocumento","index":"indicenome","x":370,"y":380,"wires":[["30282359.3e066c"]]},{"id":"6b647dff.97d2a4","type":"http in","z":"8038d84.dd63128","name":"","url":"/doc/update","method":"put","upload":false,"swaggerDoc":"","x":120,"y":480,"wires":[["97bc039e.e65e4"]]},{"id":"97bc039e.e65e4","type":"function","z":"8038d84.dd63128","name":"","func":"msg.payload = msg.payload.document; \ndelete msg.payload.document;\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":540,"wires":[["30282359.3e066c","e73ead81.9215e"]]},{"id":"e73ead81.9215e","type":"cloudant out","z":"8038d84.dd63128","name":"","cloudant":"","database":"dbapp","service":"noderedwaltercoan-cloudantNoSQLDB","payonly":true,"operation":"insert","x":470,"y":480,"wires":[]},{"id":"95c884f5.fa2218","type":"http in","z":"8038d84.dd63128","name":"","url":"/doc/remove","method":"delete","upload":false,"swaggerDoc":"","x":150,"y":600,"wires":[["652cc94a.4158e8"]]},{"id":"652cc94a.4158e8","type":"function","z":"8038d84.dd63128","name":"","func":"msg.payload = msg.payload.document; \ndelete msg.payload.document;\nreturn msg;","outputs":1,"noerr":0,"x":290,"y":660,"wires":[["773c77cd.549d68","30282359.3e066c"]]},{"id":"773c77cd.549d68","type":"cloudant out","z":"8038d84.dd63128","name":"","cloudant":"","database":"dbapp","service":"noderedwaltercoan-cloudantNoSQLDB","payonly":false,"operation":"delete","x":470,"y":600,"wires":[]}]

Add your comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.