Tutorial: Criar um aplicativo Web Node.js usando o SDK do JavaScript para gerenciar uma conta de API para NoSQL no Azure Cosmos DB
APLICA-SE A: NoSQL
Como um desenvolvedor, você pode ter aplicativos que usam dados de documentos NoSQL. Use uma conta de API para NoSQL no Azure Cosmos DB para armazenar e acessar esses dados de documentos. Este tutorial Node.js mostra como armazenar e acessar dados de uma conta da API para NoSQL no Azure Cosmos DB. O tutorial usa um aplicativo Node.js Express hospedado no recurso Aplicativo Web do Serviço de Aplicativo do Microsoft Azure. Neste tutorial, você criará um aplicativo baseado na Web (aplicativo Todo) que permite criar, recuperar e concluir tarefas. As tarefas são armazenadas como documentos JSON no Azure Cosmos DB.
Este tutorial demonstra como criar uma conta de API para NoSQL no Azure Cosmos DB usando o portal do Azure. Sem um cartão de crédito ou uma assinatura do Azure, você pode:
- Configurar uma conta do Azure Cosmos DB gratuita.
- Construir e executar um aplicativo Web que é construído sobre o SDK do Node.js para criar um banco de dados e um contêiner.
- Adicionar itens ao contêiner.
Este tutorial usa o SDK do JavaScript versão 3.0 e aborda as seguintes tarefas:
- Criar uma conta do Azure Cosmos DB
- Criar um novo aplicativo do Node.js
- Conectar o aplicativo ao Azure Cosmos DB
- Executar e implantar o aplicativo no Azure
Pré-requisitos
Antes de seguir as instruções deste artigo, verifique se você tem os seguintes recursos:
Sem uma assinatura do Azure, um cartão de crédito ou uma assinatura do Azure, você poderá configurar uma conta do Azure Cosmos DB gratuita.
Você pode experimentar o Azure Cosmos DB gratuitamente, sem uma assinatura do Azure e sem compromisso. Como alternativa, você pode criar uma conta de camada gratuita do Azure Cosmos DB, com as primeiras 1.000 RU/s e 25 GB de armazenamento gratuitos. Você também pode usar o emulador do Azure Cosmos DB com o URI
https://localhost:8081
. Quanto à chave a ser usada com o emulador, confira Autenticação de solicitações.Node.js versão 6.10 ou superior.
Gerador do Express (você pode instalar o Express usando
npm install express-generator -g
)Instale o Git na estação de trabalho local.
Criar uma conta do Azure Cosmos DB
Comece criando uma conta do Azure Cosmos DB. Se você já tiver uma conta ou se usar o Emulador do Azure Cosmos DB para este tutorial, pule para Criar um novo aplicativo do Node.js.
No menu do portal do Azure ou na Home page, selecione Criar um recurso.
Pesquise por Azure Cosmos DB. Selecione Criar>Azure Cosmos DB.
Na página Criar uma conta do Azure Cosmos DB, selecione a opção Criar na seção Azure Cosmos DB for NoSQL.
O Azure Cosmos DB fornece várias APIs:
- NoSQL, para dados do documento
- PostgreSQL
- MongoDB, para dados do documento
- Apache Cassandra
- Tabela
- Apache Gremlin, para dados do grafo
Para saber mais sobre a API para NoSQL, confira Bem-vindo(a) ao Azure Cosmos DB.
Na página Criar uma Conta do Azure Cosmos DB, insira as configurações básicas da nova conta do Azure Cosmos DB.
Configuração Valor Descrição Subscription Nome da assinatura Selecione a assinatura do Azure que você deseja usar para essa conta do Azure Cosmos DB. Grupo de recursos Nome do grupo de recursos Selecione um grupo de recursos ou selecione Criar novo, então insira um nome exclusivo para o novo grupo de recursos. Nome da Conta Um nome exclusivo Insira um nome para identificar a conta do Azure Cosmos DB. Já que documents.Azure.com é acrescentado ao nome que você fornece para criar o URI, use um nome exclusivo. O nome pode conter apenas letras minúsculas, números e o caractere de hífen (-). Deve ter de 3 a 44 caracteres. Location A região mais próxima dos usuários Selecione uma localização geográfica para hospedar a sua conta do Azure Cosmos DB. Use a localização mais próxima dos usuários para fornecer a eles acesso mais rápido aos dados. Modo de capacidade Taxa de transferência provisionada ou sem servidor Selecione Taxa de transferência provisionada para criar uma conta no modo taxa de transferência provisionada. Selecione Sem servidor para criar uma conta no modo sem servidor. Aplicar o desconto por nível gratuito do Azure Cosmos DB Aplicar ou Não aplicar Com a camada gratuita do Azure Cosmos DB, você recebe os primeiros 1000 RU/s e 25 GB de armazenamento sem custos em uma conta. Saiba mais sobre o nível gratuito. Limitar a taxa de transferência total da conta Selecionado ou não Limite a quantidade total da taxa de transferência que pode ser provisionada nessa conta. Esse limite impede encargos inesperados relacionados à taxa de transferência provisionada. Você pode atualizar ou remover esse limite depois que sua conta for criada. Você pode ter até uma conta gratuita do Azure Cosmos DB por assinatura do Azure e deve aceitar ao criar a conta. Se você não vê a opção de aplicar o desconto por nível gratuito, outra conta da assinatura já foi habilitada com o nível gratuito.
Observação
As seguintes opções não estarão disponíveis se você selecionar Sem servidor como Modo de capacidade:
- Aplicar desconto por nível gratuito
- Limitar a taxa de transferência total da conta
Na guia Distribuição global, configure os detalhes a seguir. Para este início rápido, é possível usar os valores padrão:
Configuração Valor Descrição Redundância geográfica Desabilitar Habilite ou desabilite a distribuição global em sua conta emparelhando sua região com uma região de par. Você poderá adicionar mais regiões à sua conta posteriormente. Gravações de várias regiões Desabilitar A capacidade de gravação de várias regiões permite que você aproveite a taxa de transferência provisionada para seus bancos de dados e contêineres em todo o mundo. Zonas de Disponibilidades Desabilitar As Zonas de Disponibilidade ajudam a aprimorar a disponibilidade e a resiliência do seu aplicativo. Observação
As seguintes opções não estarão disponíveis se você selecionar Sem servidor como Modo de capacidade na página anterior Noções básicas:
- Redundância geográfica
- Gravações de várias regiões
Opcionalmente, você pode configurar mais detalhes nas seguintes guias:
- Redes. Configure o acesso a partir de uma rede virtual.
- Política de Backup. Configure uma política de backup periódica ou contínua.
- Criptografia. Use uma chave gerenciada pelo serviço ou uma chave gerenciada pelo cliente.
- Marcas. Marcas são pares nome/valor que permitem categorizar recursos e exibir a cobrança consolidada por meio da aplicação da mesma marca a vários recursos e grupos de recursos.
Selecione Examinar + criar.
Examine as configurações da conta e selecione Criar. São necessários alguns minutos para criar a conta. Aguarde até que a página do portal exiba Sua implantação está concluída.
Selecione Ir para recurso para ir para a página da conta do Azure Cosmos DB.
Vá até a página da conta do Azure Cosmos DB e selecione Chaves. Copie os valores a serem usados no aplicativo Web que será criado em seguida.
Criar um novo aplicativo do Node.js
Agora, aprenda a criar um projeto Olá, Mundo em Node.js básico usando a estrutura Express.
Abra seu terminal favorito, como o prompt de comando do Node.js.
Navegue até o diretório no qual você deseja armazenar o novo aplicativo.
Use o gerador expresso para gerar um novo aplicativo chamado tarefas.
express todo
Abra o novo diretório todo e instale as dependências.
cd todo npm install
Execute o novo aplicativo.
npm start
Para exibir seu novo aplicativo em um navegador, acesse
http://localhost:3000
.Interrompa o aplicativo usando CTRL+C na janela do terminal e marque y para finalizar o trabalho em lotes.
Instalar os módulos necessários
O arquivo package.json é um dos arquivos criados na raiz do projeto. Esse arquivo contém uma lista de outros módulos que são necessários para seu aplicativo Node.js. Ao implantar esse aplicativo no Azure, esse arquivo será usado para determinar quais módulos precisam ser instalados no Azure para dar suporte ao seu aplicativo. Instale mais dois pacotes para este tutorial.
Instale o módulo @azure/cosmos via npm.
npm install @azure/cosmos
Conectar o aplicativo do Node.js ao Azure Cosmos DB
Depois de concluir a instalação e a configuração iniciais, saiba como escrever o código necessário para que o aplicativo todo se comunique com o Azure Cosmos DB.
Criar o modelo
Na raiz do diretório do projeto, crie um novo diretório chamado modelos.
No diretório models, criar um novo arquivo chamado taskDao.js. Esse arquivo contém o código necessário para criar o banco de dados e o contêiner. Ele também define métodos para ler, atualizar, criar e localizar as tarefas no Azure Cosmos DB.
Copie o código a seguir para o arquivo taskDao.js:
// @ts-check const CosmosClient = require('@azure/cosmos').CosmosClient const debug = require('debug')('todo:taskDao') // For simplicity we'll set a constant partition key const partitionKey = undefined class TaskDao { /** * Manages reading, adding, and updating Tasks in Azure Cosmos DB * @param {CosmosClient} cosmosClient * @param {string} databaseId * @param {string} containerId */ constructor(cosmosClient, databaseId, containerId) { this.client = cosmosClient this.databaseId = databaseId this.collectionId = containerId this.database = null this.container = null } async init() { debug('Setting up the database...') const dbResponse = await this.client.databases.createIfNotExists({ id: this.databaseId }) this.database = dbResponse.database debug('Setting up the database...done!') debug('Setting up the container...') const coResponse = await this.database.containers.createIfNotExists({ id: this.collectionId }) this.container = coResponse.container debug('Setting up the container...done!') } async find(querySpec) { debug('Querying for items from the database') if (!this.container) { throw new Error('Collection is not initialized.') } const { resources } = await this.container.items.query(querySpec).fetchAll() return resources } async addItem(item) { debug('Adding an item to the database') item.date = Date.now() item.completed = false const { resource: doc } = await this.container.items.create(item) return doc } async updateItem(itemId) { debug('Update an item in the database') const doc = await this.getItem(itemId) doc.completed = true const { resource: replaced } = await this.container .item(itemId, partitionKey) .replace(doc) return replaced } async getItem(itemId) { debug('Getting an item from the database') const { resource } = await this.container.item(itemId, partitionKey).read() return resource } } module.exports = TaskDao
Salve e feche o arquivo taskDao.js .
Criar o controlador
No diretório rotas do projeto, crie um novo arquivo chamado tasklist.js.
Adicione os seguintes códigos ao tasklist.js. Esse código carrega os módulos CosmosClient e assíncrono que são usados pelo tasklist.js. Ele também define a classe TaskList que é transmitida a uma instância do objeto TaskDao definido anteriormente:
const TaskDao = require("../models/TaskDao"); class TaskList { /** * Handles the various APIs for displaying and managing tasks * @param {TaskDao} taskDao */ constructor(taskDao) { this.taskDao = taskDao; } async showTasks(req, res) { const querySpec = { query: "SELECT * FROM root r WHERE r.completed=@completed", parameters: [ { name: "@completed", value: false } ] }; const items = await this.taskDao.find(querySpec); res.render("index", { title: "My ToDo List ", tasks: items }); } async addTask(req, res) { const item = req.body; await this.taskDao.addItem(item); res.redirect("/"); } async completeTask(req, res) { const completedTasks = Object.keys(req.body); const tasks = []; completedTasks.forEach(task => { tasks.push(this.taskDao.updateItem(task)); }); await Promise.all(tasks); res.redirect("/"); } } module.exports = TaskList;
Salve e feche o arquivo tasklist.js .
Adicionar config.js
Na raiz do diretório do projeto, crie um novo arquivo chamado config.js.
Adicione o código a seguir ao arquivo config.js. Esse código define as configurações e valores necessários para nosso aplicativo.
const config = {}; config.host = process.env.HOST || "[the endpoint URI of your Azure Cosmos DB account]"; config.authKey = process.env.AUTH_KEY || "[the PRIMARY KEY value of your Azure Cosmos DB account"; config.databaseId = "ToDoList"; config.containerId = "Items"; if (config.host.includes("https://localhost:")) { console.log("Local environment detected"); console.log("WARNING: Disabled checking of self-signed certs. Do not have this code in production."); process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; console.log(`Go to http://localhost:${process.env.PORT || '3000'} to try the sample.`); } module.exports = config;
No arquivo config.js, atualize os valores de HOST e de AUTH_KEY usando os valores encontrados na página Chaves de sua conta do Azure Cosmos DB no portal do Azure.
Salve e feche o arquivo config.js .
Modificar app.js
No diretório do projeto, abra o arquivo app.js . Esse arquivo foi criado anteriormente, quando o aplicativo Web Express foi criado.
Adicione o código a seguir ao arquivo app.js. Esse código define o arquivo de configuração a ser usado e carrega os valores para algumas variáveis que você usará nas próximas seções.
const CosmosClient = require('@azure/cosmos').CosmosClient const config = require('./config') const TaskList = require('./routes/tasklist') const TaskDao = require('./models/taskDao') const express = require('express') const path = require('path') const logger = require('morgan') const cookieParser = require('cookie-parser') const bodyParser = require('body-parser') const app = express() // view engine setup app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'jade') // uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(logger('dev')) app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: false })) app.use(cookieParser()) app.use(express.static(path.join(__dirname, 'public'))) //Todo App: const cosmosClient = new CosmosClient({ endpoint: config.host, key: config.authKey }) const taskDao = new TaskDao(cosmosClient, config.databaseId, config.containerId) const taskList = new TaskList(taskDao) taskDao .init(err => { console.error(err) }) .catch(err => { console.error(err) console.error( 'Shutting down because there was an error settinig up the database.' ) process.exit(1) }) app.get('/', (req, res, next) => taskList.showTasks(req, res).catch(next)) app.post('/addtask', (req, res, next) => taskList.addTask(req, res).catch(next)) app.post('/completetask', (req, res, next) => taskList.completeTask(req, res).catch(next) ) app.set('view engine', 'jade') // catch 404 and forward to error handler app.use(function(req, res, next) { const err = new Error('Not Found') err.status = 404 next(err) }) // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message res.locals.error = req.app.get('env') === 'development' ? err : {} // render the error page res.status(err.status || 500) res.render('error') }) module.exports = app
Por fim, salve e feche o arquivo app.js.
Criar uma interface do usuário
Agora crie a interface do usuário para que um usuário possa interagir com o aplicativo. O aplicativo Express que você criou na seção anterior usa Jade como o mecanismo de exibição.
O arquivo layout.jade no diretório views é usado como um modelo global para outros arquivos .jade. Nesta etapa, você o modifica para usar o Bootstrap, um kit de ferramentas usado para projetar sites da Web.
Abra o arquivo layout.jade encontrado na pasta views e substitua o conteúdo pelo seguinte código:
doctype html html head title= title link(rel='stylesheet', href='//ajax.aspnetcdn.com/ajax/bootstrap/3.3.2/css/bootstrap.min.css') link(rel='stylesheet', href='/stylesheets/style.css') body nav.navbar.navbar-inverse.navbar-fixed-top div.navbar-header a.navbar-brand(href='#') My Tasks block content script(src='//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.2.min.js') script(src='//ajax.aspnetcdn.com/ajax/bootstrap/3.3.2/bootstrap.min.js')
Esse código instrui o mecanismo Jade a renderizar um HTML para o aplicativo e cria um bloco chamado content em que podemos fornecer o layout para as páginas de conteúdo. Salve e feche o arquivo layout.jade .
Abra o arquivo index.jade, a exibição usada pelo aplicativo. Substitua o conteúdo do arquivo pelo código a seguir:
extends layout block content h1 #{title} br form(action="/completetask", method="post") table.table.table-striped.table-bordered tr td Name td Category td Date td Complete if (typeof tasks === "undefined") tr td else each task in tasks tr td #{task.name} td #{task.category} - var date = new Date(task.date); - var day = date.getDate(); - var month = date.getMonth() + 1; - var year = date.getFullYear(); td #{month + "/" + day + "/" + year} td if(task.completed) input(type="checkbox", name="#{task.id}", value="#{!task.completed}", checked=task.completed) else input(type="checkbox", name="#{task.id}", value="#{!task.completed}", checked=task.completed) button.btn.btn-primary(type="submit") Update tasks hr form.well(action="/addtask", method="post") label Item Name: input(name="name", type="textbox") label Item Category: input(name="category", type="textbox") br button.btn(type="submit") Add item
Esse código estende o layout e fornece conteúdo para o espaço reservado content que você viu no arquivo layout.jade. Naquele layout, você criou dois formulários HTML.
O primeiro formulário contém uma tabela para nossos dados e um botão que permite atualizar itens ao ser lançado o método /completeTask do controlador.
O segundo formulário contém dois campos de entrada e um botão que permite criar um novo item postando no método /addtask do controlador, que é tudo o que você precisa para que o aplicativo funcione.
Execute o seu aplicativo localmente
Depois de criar o aplicativo, você pode executá-lo localmente usando as seguintes etapas:
Para testar o aplicativo no computador local, execute
npm start
no terminal para iniciar o aplicativo e atualize a páginahttp://localhost:3000
. A página deve se parecer com a captura de tela abaixo:Dica
Se receber um erro sobre o recuo no arquivo layout.jade ou o arquivo index.jade, verifique se as duas primeiras linhas em ambos os arquivos estão justificadas à esquerda, sem espaços. Se houver espaços antes das duas primeiras linhas, remova-os, salve os dois arquivos e atualize a janela do navegador.
Use os campos Nome do Item e Categoria do Item para inserir uma nova tarefa e selecione Adicionar Item para criar um documento no Azure Cosmos DB com essas propriedades.
A página atualiza para exibir o item recém-criado na lista de Tarefas.
Para concluir uma tarefa, selecione a caixa marcar na coluna Concluir e selecione Atualizar tarefas para atualizar o documento que você já criou e removê-lo do modo de exibição.
Para interromper o aplicativo, pressione CTRL+C na janela do terminal e selecione y para finalizar o trabalho em lotes.
Implantar seu aplicativo no Serviço de Aplicativo
Depois que seu aplicativo for bem-sucedido localmente, você poderá implantá-lo no Serviço de Aplicativo do Azure. No terminal, verifique se você está no diretório de aplicativos todo. Implante o código em sua pasta local (todo) usando o seguinte comando az webapp up:
az webapp up --sku F1 --name <app-name>
Substitua <app_name> por um nome exclusivo em todo o Azure (os caracteres válidos são a-z, 0-9 e -). Um bom padrão é usar uma combinação do nome da empresa e um identificador de aplicativo. Para saber mais sobre a implantação do aplicativo, confira Implantação de aplicativo Node.js no Azure.
O comando pode levar alguns minutos para ser concluído. O comando envia mensagens sobre como criar o grupo de recursos, o plano do Serviço de Aplicativo, o recurso de aplicativo, como configurar o registro em log, bem como executar a implantação zip. O comando fornece essas mensagens durante a execução. Em seguida, ele fornece uma URL para iniciar o aplicativo em http://<app-name>.azurewebsites.net
, que é a URL do aplicativo no Azure.
Limpar os recursos
Quando esses recursos já não forem necessários, você poderá excluir o grupo de recursos, a conta do Azure Cosmos DB e todos os recursos relacionados. Para fazer isso, selecione o grupo de recursos que você usou para a conta do Azure Cosmos DB, selecione Excluir e, em seguida, confirme o nome do grupo de recursos a ser excluído.
Próximas etapas
Você pode usar informações sobre o cluster de banco de dados existente para fazer isso.