Tutorial: Criar uma aplicação Web Node.js com o SDK JavaScript para gerir uma API para conta NoSQL no Azure Cosmos DB
APLICA-SE A: NoSQL
Enquanto programador, poderá ter aplicações que utilizam dados de documentos NoSQL. Pode utilizar uma API para a conta NoSQL no Azure Cosmos DB para armazenar e aceder a estes dados do documento. Este tutorial Node.js mostra-lhe como armazenar e aceder a dados a partir de uma API para conta NoSQL no Azure Cosmos DB. O tutorial utiliza uma aplicação Node.js Express alojada na funcionalidade Aplicações Web do Microsoft Serviço de Aplicações do Azure. Neste tutorial, vai criar uma aplicação baseada na Web (aplicação Todo) que lhe permite criar, obter e concluir tarefas. As tarefas são armazenadas como documentos JSON no Azure Cosmos DB.
Este tutorial demonstra como criar uma API para uma conta NoSQL no Azure Cosmos DB com o portal do Azure. Sem um cartão de crédito ou uma subscrição do Azure, pode:
- Configure uma conta do Azure Cosmos DB gratuita.
- Crie e execute uma aplicação Web criada no SDK Node.js para criar uma base de dados e um contentor.
- Adicione itens ao contentor.
Este tutorial utiliza o SDK JavaScript versão 3.0 e abrange as seguintes tarefas:
- Criar uma conta do Azure Cosmos DB
- Criar uma nova aplicação Node.js
- Ligar a aplicação ao Azure Cosmos DB
- Executar e implementar a aplicação no Azure
Pré-requisitos
Antes de seguir as instruções deste artigo, certifique-se de que tem os seguintes recursos:
Sem uma subscrição do Azure, um cartão de crédito ou uma subscrição do Azure, pode configurar uma conta do Azure Cosmos DB gratuita.
Pode experimentar o Azure Cosmos DB gratuitamente, sem uma subscrição do Azure e sem necessidade de alocação. Em alternativa, pode criar uma conta de escalão gratuito do Azure Cosmos DB, com as primeiras 1000 RU/s e 25 GB de armazenamento gratuitamente. Também pode utilizar o emulador do Azure Cosmos DB com um URI de
https://localhost:8081
. Para a chave a utilizar com o emulador, veja Autenticar pedidos.Node.js versão 6.10 ou superior.
Express generator (pode instalar o Express através de
npm install express-generator -g
)Instale o Git na estação de trabalho local.
Criar uma conta do Azure Cosmos DB
Comece por criar uma conta do Azure Cosmos DB. Se já tiver uma conta ou se utilizar o Emulador do Azure Cosmos DB para este tutorial, pode avançar para Criar uma nova aplicação Node.js.
No menu portal do Azure ou na Home page, selecione Criar um recurso.
Procure Azure Cosmos DB. Selecione Criar>Azure Cosmos DB.
Na página Criar uma conta do Azure Cosmos DB , selecione a opção Criar na secção Azure Cosmos DB para NoSQL .
O Azure Cosmos DB fornece várias APIs:
- NoSQL, para dados de documentos
- PostgreSQL
- MongoDB, para dados de documentos
- Apache Cassandra
- Tabela
- Apache Gremlin, para dados de gráficos
Para saber mais sobre a API para NoSQL, veja Bem-vindo ao Azure Cosmos DB.
Na página Criar Conta do Azure Cosmos DB , introduza as definições básicas para a nova conta do Azure Cosmos DB.
Definição Valor Descrição Subscrição Nome da subscrição Selecione a subscrição do Azure que quer utilizar para esta conta do Azure Cosmos DB. Grupo de Recursos Nome do grupo de recursos Selecione um grupo de recursos ou selecione Criar novo e, em seguida, introduza um nome exclusivo para o novo grupo de recursos. Nome da Conta Um nome exclusivo Introduza um nome para identificar a sua conta do Azure Cosmos DB. Uma vez que documents.azure.com é anexado ao nome que indicar para criar o URI, utilize um nome exclusivo. O nome só pode conter letras minúsculas, números e o caráter de hífen (-). Tem de ter entre 3 e 44 carateres. Localização A região mais próxima dos seus utilizadores Selecione a localização geográfica para alojar a sua conta do Azure Cosmos DB. Utilize a localização mais próxima dos utilizadores para lhes dar o acesso mais rápido aos dados. Modo de capacidade Débito aprovisionado ou Sem servidor Selecione Débito aprovisionado para criar uma conta no modo de débito aprovisionado . Selecione Sem servidor para criar uma conta no modo sem servidor . Aplicar o desconto de escalão gratuito do Azure Cosmos DB Aplicar ou Não aplicar Com o escalão gratuito do Azure Cosmos DB, obtém gratuitamente as primeiras 1000 RU/s e 25 GB de armazenamento numa conta. Saiba mais sobre o escalão gratuito. Limitar débito total da conta Selecionado ou não Limite a quantidade total de débito que pode ser aprovisionada nesta conta. Este limite impede custos inesperados relacionados com o débito aprovisionado. Pode atualizar ou remover este limite após a criação da sua conta. Pode ter até uma conta do Azure Cosmos DB de escalão gratuito por subscrição do Azure e tem de optar ativamente por participar ao criar a conta. Se não vir a opção para aplicar o desconto de escalão gratuito, outra conta na subscrição já foi ativada com o escalão gratuito.
Nota
As seguintes opções não estão disponíveis se selecionar Sem servidor como modo de Capacidade:
- Aplicar Desconto de Escalão Gratuito
- Limitar débito total da conta
No separador Distribuição Global , configure os seguintes detalhes. Pode deixar os valores predefinidos para este início rápido:
Definição Valor Descrição Redundância Geográfica Desativar Ative ou desative a distribuição global na sua conta ao emparelhar a região com uma região de par. Pode adicionar mais regiões à sua conta mais tarde. Escritas de várias regiões Desativar A capacidade de escrita de várias regiões permite-lhe tirar partido do débito aprovisionado para as suas bases de dados e contentores em todo o mundo. Zonas de Disponibilidade Desativar Zonas de Disponibilidade ajudar a melhorar ainda mais a disponibilidade e a resiliência da sua aplicação. Nota
As seguintes opções não estão disponíveis se selecionar Sem servidor como o modo de Capacidade na página Básicas anterior:
- Georredundância
- Escritas de várias regiões
Opcionalmente, pode configurar mais detalhes nos seguintes separadores:
- Rede. Configurar o acesso a partir de uma rede virtual.
- Política de Cópia de Segurança. Configure uma política de cópia de segurança periódica ou contínua .
- Encriptação. Utilize uma chave gerida pelo serviço ou uma chave gerida pelo cliente.
- Etiquetas. As etiquetas são pares de nomes/valores que lhe permitem categorizar recursos e ver a faturação consolidada ao aplicar a mesma etiqueta a vários recursos e grupos de recursos.
Selecione Rever + criar.
Reveja as definições da conta e, em seguida, selecione Criar. A criação da conta demora alguns minutos. Aguarde até que a página do portal apresente A implementação está concluída.
Selecione Ir para recurso para aceder à página da conta do Azure Cosmos DB.
Aceda à página da conta do Azure Cosmos DB e selecione Chaves. Copie os valores a utilizar na aplicação Web que criar a seguir.
Criar uma nova aplicação Node.js
Agora, saiba como criar um projeto de Hello World Node.js básico com a arquitetura Express.
Abra o seu terminal favorito, como a linha de comandos Node.js.
Navegue para o diretório no qual pretende armazenar a nova aplicação.
Utilizar o Express generator para gerar uma nova aplicação designada todo.
express todo
Abra o diretório todo e instale as dependências.
cd todo npm install
Execute a nova aplicação.
npm start
Para ver a sua nova aplicação num browser, aceda a
http://localhost:3000
.Pare a aplicação com CTRL+C na janela do terminal e selecione y para terminar a tarefa de lote.
Instalar os módulos necessários
O ficheiro package.json é um dos ficheiros criados na raiz do projeto. Este ficheiro contém uma lista de outros módulos necessários para a sua aplicação Node.js. Quando implementar esta aplicação no Azure, este ficheiro servirá para determinar quais os módulos que devem estar instalados no Azure para suportar a sua aplicação. Instale mais dois pacotes para este tutorial.
Instale o módulo @azure/cosmos através do npm.
npm install @azure/cosmos
Ligar a aplicação Node.js ao Azure Cosmos DB
Depois de concluir a configuração inicial, saiba como escrever o código que a aplicação todo necessita para comunicar com o Azure Cosmos DB.
Criar o modelo
Na raiz do diretório do projeto, crie um novo diretório com o nome modelos.
No diretório modelos, crie um novo ficheiro designado taskDao.js. Este ficheiro contém o código necessário para criar a base de dados e o contentor. Também define métodos para ler, atualizar, criar e localizar tarefas no Azure Cosmos DB.
Copie o seguinte código para o ficheiro 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
Guarde e feche o ficheiro taskDao.js.
Criar o controlador
No diretório rotas do seu projeto, crie um novo ficheiro designado tasklist.js.
Adicione o seguinte código ao tasklist.js. Este código carrega os módulos CosmosClient e async, que são utilizados por tasklist.js. Este código também define a classe TaskList, que é transmitida como uma instância do objeto TaskDao que definimos 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;
Guarde e feche o ficheiro tasklist.js.
Adicionar config.js
Na raiz do diretório do projeto, crie um ficheiro novo designado config.js.
Adicione o seguinte código ao ficheiro config.js. Este código define os parâmetros e os valores da configuração necessários para a nossa aplicação.
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 ficheiro config.js, atualize os valores de HOST e AUTH_KEY com os valores encontrados na página Chaves da sua conta do Azure Cosmos DB no portal do Azure.
Guarde e feche o ficheiro config.js.
Modificar app.js
No diretório do projeto, abra o ficheiro app.js. Este ficheiro foi criado anteriormente, aquando da criação da aplicação Web Express.
Adicione o seguinte código ao ficheiro app.js. Este código define o ficheiro de configuração a ser utilizado e carrega os valores para algumas variáveis que irá utilizar nas secções seguintes.
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, guarde e feche o ficheiro app.js.
Criar uma interface de utilizador
Agora, crie a interface de utilizador para que um utilizador possa interagir com a aplicação. A aplicação Express que criou nas secções anteriores utiliza o Jade como motor de visualização.
O ficheiro layout.jade no diretório vistas é utilizado como um modelo global para outros ficheiros .jade. Neste passo, vai modificá-lo para utilizar o Twitter Bootstrap, que é um toolkit utilizado para criar um site.
Abra o ficheiro 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')
Este código indica ao motor jade para compor algum HTML para a aplicação e cria um bloco chamado conteúdo onde pode fornecer o esquema para as páginas de conteúdo. Guarde e feche o ficheiro layout.jade.
Abra o ficheiro index.jade , a vista utilizada pela aplicação. Substitua o conteúdo do ficheiro pelo seguinte código:
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
Este código expande o esquema e fornece conteúdo para o marcador de posição de conteúdo que viu no ficheiro layout.jade . Nesse esquema, criou dois formulários HTML.
O primeiro formulário contém uma tabela para os seus dados e um botão que lhe permite atualizar itens ao publicar no método /completeTask do controlador.
O segundo formulário contém dois campos de entrada e um botão que lhe permite criar um novo item ao publicar no método /addtask do controlador, que é tudo o que precisa para que a aplicação funcione.
Executar a sua aplicação localmente
Depois de criar a aplicação, pode executá-la localmente com os seguintes passos:
Para testar a aplicação no seu computador local, execute
npm start
no terminal para iniciar a aplicação e, em seguida, atualize ahttp://localhost:3000
página. A página deverá agora ter o seguinte aspeto de captura de ecrã:Dica
Se receber um erro sobre o avanço no ficheiro layout.jade ou no ficheiro index.jade , certifique-se de que as duas primeiras linhas em ambos os ficheiros são justificadas sem espaços. Se existirem espaços antes das duas primeiras linhas, remova-os, guarde ambos os ficheiros e, em seguida, atualize a janela do browser.
Utilize os campos Nome do Item e Categoria de Item para introduzir uma nova tarefa e, em seguida, selecione Adicionar Item para criar um documento no Azure Cosmos DB com essas propriedades.
A página é atualizada para apresentar o item criado recentemente na lista ToDo.
Para concluir uma tarefa, selecione a caixa de verificação na coluna Concluir e, em seguida, selecione Atualizar tarefas para atualizar o documento que já criou e removê-lo da vista.
Para parar a aplicação, prima CTRL+C na janela do terminal e, em seguida, selecione y para terminar a tarefa de lote.
Implementar a sua aplicação no Serviço de Aplicações
Depois de a sua aplicação ter êxito localmente, pode implementá-la no Serviço de Aplicações do Azure. No terminal, certifique-se de que está no diretório da aplicação todo . Implemente o código na pasta local (todo) com 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 carateres válidos são a-z, 0-9 e -). Um bom padrão é utilizar uma combinação do nome da sua empresa e de um identificador de aplicação. Para saber mais sobre a implementação de aplicações, veja Node.js implementação de aplicações no Azure.
O comando pode demorar alguns minutos a concluir. O comando fornece mensagens sobre como criar o grupo de recursos, o plano Serviço de Aplicações e o recurso da aplicação, configurando o registo e efetuando a implementação ZIP. O comando fornece estas mensagens durante a execução. Em seguida, dá-lhe um URL para iniciar a aplicação em http://<app-name>.azurewebsites.net
, que é o URL da aplicação no Azure.
Limpar os recursos
Quando estes recursos já não forem necessários, pode eliminar o grupo de recursos, a conta do Azure Cosmos DB e todos os recursos relacionados. Para tal, selecione o grupo de recursos que utilizou para a conta do Azure Cosmos DB, selecione Eliminar e, em seguida, confirme o nome do grupo de recursos a eliminar.
Passos seguintes
Pode utilizar informações sobre o cluster de bases de dados existentes para o planeamento de capacidade.