Esercitazione: Creare un'app Web Node.js usando JavaScript SDK per gestire un account API per NoSQL in Azure Cosmos DB

SI APPLICA A: NoSQL

Gli sviluppatori possono avere applicazioni che usano dati documento NoSQL. È possibile usare un'API per l'account NoSQL in Azure Cosmos DB per archiviare e accedere ai dati del documento. Questa esercitazione Node.js illustra come archiviare e accedere ai dati da un account API per NoSQL in Azure Cosmos DB. L'esercitazione usa un'applicazione express Node.js ospitata nella funzionalità App Web di Microsoft Servizio app di Azure. In questa esercitazione viene creata un'applicazione basata sul Web (app Todo) che consente di creare, recuperare e completare le attività. Le attività vengono memorizzate come documenti JSON in Azure Cosmos DB.

Questa esercitazione illustra come creare un account API per NoSQL in Azure Cosmos DB usando la portale di Azure. Senza una carta di credito o una sottoscrizione di Azure, è possibile:

  • Configurare un account Azure Cosmos DB gratuito.
  • Creare ed eseguire un'app Web basata sull'SDK di Node.js per creare un database e un contenitore.
  • Aggiungere elementi al contenitore.

Questa esercitazione usa JavaScript SDK versione 3.0 e illustra le attività seguenti:

  • Creare un account Azure Cosmos DB
  • Creare una nuova applicazione Node.js
  • Connettere l'applicazione ad Azure Cosmos DB
  • Eseguire e distribuire l'applicazione in Azure

Prerequisiti

Prima di seguire le istruzioni di questo articolo, verificare di disporre delle risorse seguenti:

Creare un account Azure Cosmos DB

Iniziare creando un account Azure Cosmos DB. Se si ha già un account o se si usa l'emulatore azure Cosmos DB per questa esercitazione, è possibile passare a Creare una nuova applicazione Node.js.

  1. Nel menu del portale di Azure o dalla pagina Home selezionare Crea una risorsa.

  2. Cercare Azure Cosmos DB. Selezionare Crea>Azure Cosmos DB.

  3. Nella pagina Crea un account Azure Cosmos DB selezionare l'opzione Crea nella sezione Azure Cosmos DB for NoSQL .

    Azure Cosmos DB offre diverse API:

    • NoSQL, per i dati dei documenti
    • PostgreSQL
    • MongoDB, per i dati dei documenti
    • Apache Cassandra
    • Tabella
    • Apache Gremlin, per i dati del grafico

    Per altre informazioni sull'API per NoSQL, vedere Benvenuto in Azure Cosmos DB.

  4. Nella pagina Crea account Azure Cosmos DB immettere le impostazioni di base per il nuovo account Azure Cosmos DB.

    Impostazione Valore Descrizione
    Subscription Nome sottoscrizione Selezionare la sottoscrizione di Azure da usare per l'account Azure Cosmos DB.
    Gruppo di risorse Nome del gruppo di risorse Selezionare un gruppo di risorse oppure fare clic su Crea nuovo, quindi immettere un nome univoco per il nuovo gruppo di risorse.
    Nome account Un nome univoco Immettere un nome per identificare l'account Azure Cosmos DB. Dato che al nome specificato viene aggiunto documents.azure.com per creare l'URI, usare un nome univoco. Il nome può contenere solo lettere minuscole, numeri e il trattino (-). Deve essere 3-44 caratteri.
    Location Area più vicina ai propri utenti Selezionare una posizione geografica in cui ospitare l'account Azure Cosmos DB. Usare la località più vicina agli utenti per offrire loro la massima velocità di accesso ai dati.
    Modalità di capacità Velocità effettiva con provisioning o serverless Selezionare Provisioning velocità effettiva per creare un account in modalità Provisioning velocità effettiva. Selezionare Serverless per creare un account in modalità Serverless.
    Applicare lo sconto in base al livello gratuito di Azure Cosmos DB Applicare o non applicare Con il livello gratuito di Azure Cosmos DB si ottengono i primi 1000 UR/s e 25 GB di archiviazione gratuitamente in un account. Altre informazioni sul livello gratuito.
    Limitare la velocità effettiva totale dell'account Selezionato o meno Limitare la quantità totale di velocità effettiva che è possibile effettuare il provisioning in questo account. Questo limite impedisce addebiti imprevisti correlati alla velocità effettiva di cui è stato effettuato il provisioning. È possibile aggiornare o rimuovere questo limite dopo la creazione dell'account.

    È possibile disporre di un massimo di un account azure Cosmos DB a livello gratuito per sottoscrizione di Azure e deve acconsentire esplicitamente quando si crea l'account. Se non viene visualizzata l'opzione per applicare lo sconto gratuito, un altro account nella sottoscrizione è già stato abilitato con il livello gratuito.

    Screenshot che mostra la pagina Crea account Azure Cosmos DB.

    Nota

    Le opzioni seguenti non sono disponibili se si seleziona Serverless come modalità di capacità:

    • Applica sconto per il livello gratuito
    • Limitare la velocità effettiva totale dell'account
  5. Nella scheda Distribuzione globale configurare i dettagli seguenti. È possibile lasciare i valori predefiniti per questa guida introduttiva:

    Impostazione Valore Descrizione
    Ridondanza geografica Disabilita Abilitare o disabilitare la distribuzione globale nell'account associando la propria area a un'altra area. È possibile aggiungere altre aree al proprio account in un secondo momento.
    Scritture in più aree Disabilita La funzionalità Scritture in più aree consente di sfruttare la velocità effettiva di cui è stato effettuato il provisioning per i database e i contenitori in tutto il mondo.
    Zone di disponibilità Disabilita Le zone di disponibilità consentono di migliorare ulteriormente la disponibilità e la resilienza dell'applicazione.

    Nota

    Le opzioni seguenti non sono disponibili se si seleziona Serverless come modalità capacità nella pagina Nozioni di base precedenti:

    • Ridondanza geografica
    • Scritture in più aree
  6. Facoltativamente, è possibile configurare altri dettagli nelle schede seguenti:

    • Funzionalità di rete. Configurare l'accesso da una rete virtuale.
    • Criteri di backup. Configurare criteri di backup periodici o continui .
    • Crittografia. Usare una chiave gestita dal servizio o una chiave gestita dal cliente.
    • Tag. I tag sono coppie nome-valore che consentono di classificare le risorse e visualizzare dati di fatturazione consolidati tramite l'applicazione dello stesso tag a più risorse e gruppi di risorse.
  7. Selezionare Rivedi e crea.

  8. Esaminare le impostazioni dell'account e quindi selezionare Crea. La creazione dell'account richiede alcuni minuti. Attendere che la pagina del portale visualizzi La distribuzione è stata completata.

    Screenshot che mostra che la distribuzione è stata completata.

  9. Selezionare Vai alla risorsa per passare alla pagina dell'account Azure Cosmos DB.

    Screenshot che mostra la pagina dell'account Azure Cosmos DB.

Passare alla pagina dell'account Azure Cosmos DB e selezionare Chiavi. Copiare i valori da usare nell'applicazione Web che verrà creata successivamente.

Screenshot del portale di Azure con il pulsante Chiavi evidenziato nella pagina dell'account Azure Cosmos DB

Creare una nuova applicazione Node.js

Informazioni su come creare un progetto di base Hello World Node.js usando il framework Express.

  1. Aprire il terminale preferito, ad esempio il prompt dei comandi di Node.js.

  2. Passare alla directory in cui si vuole archiviare la nuova applicazione.

  3. Usare il generatore di Express per generare una nuova applicazione denominata todo.

    express todo
    
  4. Aprire la directory todo e installare le dipendenze.

    cd todo
    npm install
    
  5. Eseguire la nuova applicazione.

    npm start
    
  6. Per visualizzare la nuova applicazione in un browser, passare a http://localhost:3000.

    Screenshot dell'applicazione Hello World in una finestra del browser.

    Per arrestare l'applicazione, usare CTRL+C nella finestra del terminale e selezionare y per terminare il processo batch.

Installare i moduli necessari

Il file package.json è uno di quelli creati nella radice del progetto. Questo file contiene un elenco di altri moduli necessari per l'applicazione Node.js. Quando si distribuisce questa applicazione in Azure, questo file viene usato per determinare quali moduli devono essere installati in Azure per supportare l'applicazione. Per questa esercitazione, installare altri due pacchetti.

  1. Installare il modulo @azure/cosmos tramite npm.

    npm install @azure/cosmos
    

Connettere l'applicazione Node.js ad Azure Cosmos DB

Dopo aver completato la configurazione e la configurazione iniziale, informazioni su come scrivere il codice richiesto dall'applicazione todo per comunicare con Azure Cosmos DB.

Creare il modello

  1. Nella radice della directory del progetto creare una nuova directory denominata models.

  2. Nella directory models (modelli) creare un nuovo file denominato taskDao.js. Questo file contiene il codice necessario per creare il contenitore e il database. Definisce inoltre i metodi per leggere, aggiornare, creare e trovare le attività in Azure Cosmos DB.

  3. Copiare il codice seguente nel file 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
    
  4. Salvare e chiudere il file taskDao.js .

Creare il controller

  1. Nella directory routes (route) del progetto creare un nuovo file denominato tasklist.js.

  2. Aggiungere il seguente codice al file tasklist.js. Questo codice carica i moduli CosmosClient e async, usati da tasklist.js. Definisce inoltre la classe TaskList, che viene passata come istanza dell'oggetto TaskDao definito in precedenza:

     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;
    
  3. Salvare e chiudere il file tasklist.js .

Aggiungere config.json

  1. Nella radice della directory del progetto creare un nuovo file denominato config.js.

  2. Aggiungere il codice seguente al file config.js. Questo codice definisce le impostazioni e i valori di configurazione necessari per l'applicazione.

    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;
    
  3. Nel file config.js aggiornare i valori di HOST e AUTH_KEY usando i valori trovati nella pagina Chiavi dell'account Azure Cosmos DB nel portale di Azure.

  4. Salvare e chiudere il file config.js .

Modificare il file app.js

  1. Nella directory del progetto aprire il file app.js . Questo file è stato creato in precedenza quando è stata creata l'applicazione Web Express.

  2. Aggiungere il codice seguente al file app.js. Questo codice definisce il file di configurazione da usare e carica i valori in alcune variabili che verranno usate nelle sezioni successive.

     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
    
  3. Infine, salvare e chiudere il file app.js.

Creare un'interfaccia utente

Compilare ora l'interfaccia utente in modo che un utente possa interagire con l'applicazione. L'applicazione Express creata nelle sezioni precedenti usa Jade come motore di visualizzazione.

  1. Il file layout.jade della directory views viene usato come modello globale per altri file .jade. In questo passaggio viene modificato in modo da usare Twitter Bootstrap, che è un toolkit usato per progettare un sito Web.

  2. Aprire il file layout.jade nella cartella views e sostituire il contenuto con il codice seguente:

    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')
    

    Questo codice indica al motore Jade di eseguire il rendering di alcuni HTML per l'applicazione e crea un blocco denominato contenuto in cui è possibile specificare il layout per le pagine del contenuto. Salvare e chiudere il file layout.jade.

  3. Aprire il file index.jade , la visualizzazione usata dall'applicazione. Sostituire il contenuto del file con il codice seguente:

    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
    

Questo codice estende il layout e fornisce contenuto per il segnaposto contenuto visualizzato nel file layout.jade . In tale layout sono stati creati due moduli HTML.

Il primo modulo contiene una tabella per i dati e un pulsante che consente di aggiornare gli elementi pubblicando al metodo /completeTask del controller.

Il secondo modulo contiene due campi di input e un pulsante che consente di creare un nuovo elemento registrando al metodo /addtask del controller, che è tutto necessario per il funzionamento dell'applicazione.

Esecuzione dell'applicazione in locale

Dopo aver compilato l'applicazione, è possibile eseguirla in locale usando la procedura seguente:

  1. Per testare l'applicazione nel computer locale, eseguire npm start nel terminale per avviare l'applicazione e quindi aggiornare la http://localhost:3000 pagina. La pagina dovrebbe ora essere simile alla schermata seguente:

    Screenshot dell'applicazione My Todo List in un browser.

    Suggerimento

    Se viene visualizzato un errore relativo al rientro nel file layout.jade o al file index.jade, assicurarsi che le prime due righe in entrambi i file siano giustificate senza spazi. Se sono presenti spazi davanti alle prime due righe, rimuoverli, salvare entrambi i file e quindi aggiornare la finestra del browser.

  2. Usare i campi Nome elemento e Categoria elemento per immettere una nuova attività e quindi selezionare Aggiungi elemento per creare un documento in Azure Cosmos DB con queste proprietà.

  3. La pagina viene aggiornata per visualizzare l'elemento appena creato nell'elenco ToDo.

    Screenshot dell'applicazione con un nuovo elemento nell'elenco ToDo.

  4. Per completare un'attività, selezionare la casella di controllo nella colonna Completa e quindi selezionare Aggiorna attività per aggiornare il documento già creato e rimuoverlo dalla visualizzazione.

  5. Per arrestare l'applicazione, premere CTRL+C nella finestra del terminale e quindi selezionare y per terminare il processo batch.

Distribuire l'applicazione in servizio app

Dopo aver completato l'applicazione in locale, è possibile distribuirla in Servizio app di Azure. Nel terminale assicurarsi di essere nella directory dell'app todo . Distribuire il codice nella cartella locale (todo) usando il comando az webapp up seguente:

az webapp up --sku F1 --name <app-name>

Sostituire <app_name> con un nome univoco in tutti i tipi di Azure (i caratteri validi sono a-z, 0-9 e -). Un criterio valido consiste nell'usare una combinazione del nome della società e di un identificatore dell'app. Per altre informazioni sulla distribuzione dell'app, vedere distribuzione di appNode.js in Azure.

Il comando potrebbe richiedere alcuni minuti per completare. Il comando fornisce messaggi sulla creazione del gruppo di risorse, il piano di servizio app e la risorsa dell'app, la configurazione della registrazione e l'esecuzione della distribuzione ZIP. Il comando fornisce questi messaggi durante l'esecuzione. Fornisce quindi un URL per avviare l'app in http://<app-name>.azurewebsites.net, ovvero l'URL dell'app in Azure.

Pulire le risorse

Quando queste risorse non sono più necessarie, è possibile eliminare il gruppo di risorse, l'account Azure Cosmos DB e tutte le risorse correlate. A tale scopo, selezionare il gruppo di risorse usato per l'account Azure Cosmos DB, selezionare Elimina, quindi confermare il nome del gruppo di risorse da eliminare.

Passaggi successivi

È possibile usare le informazioni del cluster di database esistente per la pianificazione della capacità.