Tutorial: Build a Node.js console app with the JavaScript SDK to manage Azure Cosmos DB SQL API data

APPLIES TO: SQL API

As a developer, you might have applications that use NoSQL document data. You can use a SQL API account in Azure Cosmos DB to store and access this document data. This tutorial shows you how to build a Node.js console application to create Azure Cosmos DB resources and query them.

In this tutorial, you will:

  • Create and connect to an Azure Cosmos DB account.
  • Set up your application.
  • Create a database.
  • Create a container.
  • Add items to the container.
  • Perform basic operations on the items, container, and database.

Prerequisites

Make sure you have the following resources:

Create Azure Cosmos DB account

Let's create an Azure Cosmos DB account. If you already have an account you want to use, you can skip ahead to Set up your Node.js application. If you are using the Azure Cosmos DB Emulator, follow the steps at Azure Cosmos DB Emulator to set up the emulator and skip ahead to Set up your Node.js application.

  1. From the Azure portal menu or the Home page, select Create a resource.

  2. On the New page, search for and select Azure Cosmos DB.

  3. On the Azure Cosmos DB page, select Create.

  4. On the Create Azure Cosmos DB Account page, enter the basic settings for the new Azure Cosmos account.

    Setting Value Description
    Subscription Subscription name Select the Azure subscription that you want to use for this Azure Cosmos account.
    Resource Group Resource group name Select a resource group, or select Create new, then enter a unique name for the new resource group.
    Account Name A unique name Enter a name to identify your Azure Cosmos account. Because documents.azure.com is appended to the name that you provide to create your URI, use a unique name.

    The name can only contain lowercase letters, numbers, and the hyphen (-) character. It must be between 3-44 characters in length.
    API The type of account to create Select Core (SQL) to create a document database and query by using SQL syntax.

    The API determines the type of account to create. Azure Cosmos DB provides five APIs: Core (SQL) and MongoDB for document data, Gremlin for graph data, Azure Table, and Cassandra. Currently, you must create a separate account for each API.
    Capacity mode Provisioned throughput or Serverless Select Provisioned throughput to create an account in provisioned throughput mode. Select Serverless to create an account in serverless mode.

    Note: Serverless is currently available for Core (SQL) API accounts only.
    Apply Free Tier Discount Apply or Do not apply With Azure Cosmos DB free tier, you will get the first 400 RU/s and 5 GB of storage for free in an account. Learn more about free tier.
    Location The region closest to your users Select a geographic location to host your Azure Cosmos DB account. Use the location that is closest to your users to give them the fastest access to the data.
    Account Type Production or Non-Production Select Production if the account will be used for a production workload. Select Non-Production if the account will be used for non-production, e.g. development, testing, QA, or staging. This is an Azure resource tag setting that tunes the Portal experience but does not affect the underlying Azure Cosmos DB account. You can change this value anytime.

    Note

    You can have up to one free tier Azure Cosmos DB account per Azure subscription and must opt-in when creating the account. If you do not see the option to apply the free tier discount, this means another account in the subscription has already been enabled with free tier.

    Note

    The following options are not available if you select Serverless as the Capacity mode:

    • Apply Free Tier Discount
    • Geo-redundancy
    • Multi-region Writes

    The new account page for Azure Cosmos DB

  5. Select Review + create. You can skip the Network and Tags sections.

  6. Review the account settings, and then select Create. It takes a few minutes to create the account. Wait for the portal page to display Your deployment is complete.

    The Azure portal Notifications pane

  7. Select Go to resource to go to the Azure Cosmos DB account page.

    The Azure Cosmos DB account page

Set up your Node.js application

Before you start writing code to build the application, you can build the framework for your app. Run the following steps to set up your Node.js application that has the framework code:

  1. Open your favorite terminal.

  2. Locate the folder or directory where you'd like to save your Node.js application.

  3. Create empty JavaScript files with the following commands:

    • Windows:

      • fsutil file createnew app.js 0
      • fsutil file createnew config.js 0
      • md data
      • fsutil file createnew data\databaseContext.js 0
    • Linux/OS X:

      • touch app.js
      • touch config.js
      • mkdir data
      • touch data/databaseContext.js
  4. Create and initialize a package.json file. Use the following command:

    • npm init -y
  5. Install the @azure/cosmos module via npm. Use the following command:

    • npm install @azure/cosmos --save

Set your app's configurations

Now that your app exists, you need to make sure it can talk to Azure Cosmos DB. By updating a few configuration settings, as shown in the following steps, you can set your app to talk to Azure Cosmos DB:

  1. Open the config.js file in your favorite text editor.

  2. Copy and paste the following code snippet into the config.js file and set the properties endpoint and key to your Azure Cosmos DB endpoint URI and primary key. The database, container names are set to Tasks and Items. The partition key you will use for this application is /category.

    // @ts-check
    
    const config = {
      endpoint: "<Your Azure Cosmos account URI>",
      key: "<Your Azure Cosmos account key>",
      databaseId: "Tasks",
      containerId: "Items",
      partitionKey: { kind: "Hash", paths: ["/category"] }
    };
    
    module.exports = config;
    

    You can find the endpoint and key details in the Keys pane of the Azure portal.

    Get keys from Azure portal screenshot

The JavaScript SDK uses the generic terms container and item. A container can be a collection, graph, or table. An item can be a document, edge/vertex, or row, and is the content inside a container. In the previous code snippet, the module.exports = config; code is used to export the config object, so that you can reference it within the app.js file.

Create a database and a container

  1. Open the databaseContext.js file in your favorite text editor.

  2. Copy and paste the following code to the databaseContext.js file. This code defines a function that creates the "Tasks", "Items" database and the container if they don't already exist in your Azure Cosmos account:

    const config = require("../config");
    const CosmosClient = require("@azure/cosmos").CosmosClient;
    
    /*
    // This script ensures that the database is setup and populated correctly
    */
    async function create(client, databaseId, containerId) {
      const partitionKey = config.partitionKey;
    
      /**
       * Create the database if it does not exist
       */
      const { database } = await client.databases.createIfNotExists({
        id: databaseId
      });
      console.log(`Created database:\n${database.id}\n`);
    
      /**
       * Create the container if it does not exist
       */
      const { container } = await client
        .database(databaseId)
        .containers.createIfNotExists(
          { id: containerId, partitionKey },
          { offerThroughput: 400 }
        );
    
      console.log(`Created container:\n${container.id}\n`);
    }
    
    module.exports = { create };
    

    A database is the logical container of items partitioned across containers. You create a database by using either the createIfNotExists or create function of the Databases class. A container consists of items which in the case of the SQL API is JSON documents. You create a container by using either the createIfNotExists or create function from the Containers class. After creating a container, you can store and query the data.

    Warning

    Creating a container has pricing implications. Visit our pricing page so you know what to expect.

Import the configuration

  1. Open the app.js file in your favorite text editor.

  2. Copy and paste the code below to import the @azure/cosmos module, the configuration, and the databaseContext that you defined in the previous steps.

    const CosmosClient = require("@azure/cosmos").CosmosClient;
    const config = require("./config");
    const dbContext = require("./data/databaseContext");
    

Connect to the Azure Cosmos account

In the app.js file, copy and paste the following code to use the previously saved endpoint and key to create a new CosmosClient object.

const { endpoint, key, databaseId, containerId } = config;

const client = new CosmosClient({ endpoint, key });

const database = client.database(databaseId);
const container = database.container(containerId);

// Make sure Tasks database is already setup. If not, create it.
await dbContext.create(client, databaseId, containerId);

Note

If connecting to the Cosmos DB Emulator, disable TLS verification for your node process:

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const client = new CosmosClient({ endpoint, key });

Now that you have the code to initialize the Azure Cosmos DB client, let's take a look at how to work with Azure Cosmos DB resources.

Query items

Azure Cosmos DB supports rich queries against JSON items stored in each container. The following sample code shows a query that you can run against the items in your container.You can query the items by using the query function of the Items class. Add the following code to the app.js file to query the items from your Azure Cosmos account:

console.log(`Querying container: Items`);

// query to return all items
const querySpec = {
  query: "SELECT * from c"
};

// read all items in the Items container
const { resources: items } = await container.items
  .query(querySpec)
  .fetchAll();

items.forEach(item => {
  console.log(`${item.id} - ${item.description}`);
});

Create an item

An item can be created by using the create function of the Items class. When you're using the SQL API, items are projected as documents, which are user-defined (arbitrary) JSON content. In this tutorial, you create a new item within the tasks database.

  1. In the app.js file, define the item definition:

    const newItem = {
      id: "3",
      category: "fun",
      name: "Cosmos DB",
      description: "Complete Cosmos DB Node.js Quickstart ⚡",
      isComplete: false
    };
    
  2. Add the following code to create the previously defined item:

    /** Create new item
     * newItem is defined at the top of this file
     */
    const { resource: createdItem } = await container.items.create(newItem);
    
    console.log(`\r\nCreated new item: ${createdItem.id} - ${createdItem.description}\r\n`);
    

Update an item

Azure Cosmos DB supports replacing the contents of items. Copy and paste the following code to app.js file. This code gets an item from the container and updates the isComplete field to true.

/** Update item
 * Pull the id and partition key value from the newly created item.
 * Update the isComplete field to true.
 */
const { id, category } = createdItem;

createdItem.isComplete = true;

const { resource: updatedItem } = await container
  .item(id, category)
  .replace(createdItem);

console.log(`Updated item: ${updatedItem.id} - ${updatedItem.description}`); 
console.log(`Updated isComplete to ${updatedItem.isComplete}\r\n`);

Delete an item

Azure Cosmos DB supports deleting JSON items. The following code shows how to get an item by its ID and delete it. Copy and paste the following code to app.js file:

/**
 * Delete item
 * Pass the id and partition key value to delete the item
 */
const { resource: result } = await container.item(id, category).delete();
console.log(`Deleted item with id: ${id}`);

Run your Node.js application

Altogether, your code should look like this:

// @ts-check
//  <ImportConfiguration>
const CosmosClient = require("@azure/cosmos").CosmosClient;
const config = require("./config");
const dbContext = require("./data/databaseContext");
//  </ImportConfiguration>

//  <DefineNewItem>
const newItem = {
  id: "3",
  category: "fun",
  name: "Cosmos DB",
  description: "Complete Cosmos DB Node.js Quickstart ⚡",
  isComplete: false
};
//  </DefineNewItem>

async function main() {
  
  // <CreateClientObjectDatabaseContainer>
  const { endpoint, key, databaseId, containerId } = config;

  const client = new CosmosClient({ endpoint, key });

  const database = client.database(databaseId);
  const container = database.container(containerId);

  // Make sure Tasks database is already setup. If not, create it.
  await dbContext.create(client, databaseId, containerId);
  // </CreateClientObjectDatabaseContainer>
  
  try {
    // <QueryItems>
    console.log(`Querying container: Items`);

    // query to return all items
    const querySpec = {
      query: "SELECT * from c"
    };
    
    // read all items in the Items container
    const { resources: items } = await container.items
      .query(querySpec)
      .fetchAll();

    items.forEach(item => {
      console.log(`${item.id} - ${item.description}`);
    });
    // </QueryItems>
    
    // <CreateItem>
    /** Create new item
     * newItem is defined at the top of this file
     */
    const { resource: createdItem } = await container.items.create(newItem);
    
    console.log(`\r\nCreated new item: ${createdItem.id} - ${createdItem.description}\r\n`);
    // </CreateItem>
    
    // <UpdateItem>
    /** Update item
     * Pull the id and partition key value from the newly created item.
     * Update the isComplete field to true.
     */
    const { id, category } = createdItem;

    createdItem.isComplete = true;

    const { resource: updatedItem } = await container
      .item(id, category)
      .replace(createdItem);

    console.log(`Updated item: ${updatedItem.id} - ${updatedItem.description}`); 
    console.log(`Updated isComplete to ${updatedItem.isComplete}\r\n`);
    // </UpdateItem>
    
    // <DeleteItem>    
    /**
     * Delete item
     * Pass the id and partition key value to delete the item
     */
    const { resource: result } = await container.item(id, category).delete();
    console.log(`Deleted item with id: ${id}`);
    // </DeleteItem>  
    
  } catch (err) {
    console.log(err.message);
  }
}

main();

In your terminal, locate your app.js file and run the command:

node app.js

You should see the output of your get started app. The output should match the example text below.

Created database:
Tasks

Created container:
Items

Querying container: Items
1 - Pick up apples and strawberries.

Created new item: 3 - Complete Cosmos DB Node.js Quickstart ⚡

Updated item: 3 - Complete Cosmos DB Node.js Quickstart ⚡
Updated isComplete to true

Deleted item with id: 3

Get the complete Node.js tutorial solution

If you didn't have time to complete the steps in this tutorial, or just want to download the code, you can get it from GitHub.

To run the getting started solution that contains all the code in this article, you will need:

Install the project's dependencies via npm. Use the following command:

  • npm install

Next, in the config.js file, update the config.endpoint and config.key values as described in Step 3: Set your app's configurations.

Then in your terminal, locate your app.js file and run the command:

node app.js 

Clean up resources

When these resources are no longer needed, you can delete the resource group, Azure Cosmos DB account, and all the related resources. To do so, select the resource group that you used for the Azure Cosmos DB account, select Delete, and then confirm the name of the resource group to delete.

Next steps