Edit

Share via


Build a Node.js console app with Azure Cosmos DB for MongoDB vCore

This guide helps you build a Node.js console application to connect to an Azure Cosmos DB for MongoDB vCore cluster. You prepare your development environment, use the @azure/identity package from the Azure SDK for JavaScript to authenticate, and perform common operations on documents in the database.

Prerequisites

  • An existing Azure Cosmos DB for MongoDB (vCore) cluster.
  • Microsoft Entra authentication configured for the cluster with your identity granted dbOwner role.

  • Latest long-term support (LTS) version of Node

Configure your console application

Next, create a new console application project and import the necessary libraries to authenticate to your cluster.

  1. Create a new directory for your project and initialize it with npm init.

    mkdir cosmos-mongodb-app
    cd cosmos-mongodb-app
    npm init -y
    
  2. Set up TypeScript in your project.

    npm install typescript ts-node @types/node --save-dev
    npx tsc --init
    
  3. Create the main app.ts TypeScript file for your application.

    touch app.ts
    
  4. Install the @azure/identity library for authentication.

    npm install @azure/identity
    
  5. Install the mongodb library.

    npm install mongodb
    

Connect to the cluster

Now, use the Azure.Identity library to get a TokenCredential to use to connect to your cluster. The official MongoDB driver has a special interface that must be implemented to obtain tokens from Microsoft Entra for use when connecting to the cluster.

  1. Import the necessary modules at the top of your JavaScript file.

    import { MongoClient } from 'mongodb';
    import { DefaultAzureCredential } from '@azure/identity';
    
  2. Create a token callback function that obtains tokens from the TokenCredential instance when required.

    const azureIdentityTokenCallback = async (_, credential) => {
        const tokenResponse = await credential.getToken(['https://ossrdbms-aad.database.windows.net/.default']);
    
        if (!tokenResponse || !tokenResponse.token) {
            throw new Error('Failed to retrieve a valid access token.');
        }
    
        return {
            accessToken: tokenResponse.token,
            expiresInSeconds: Math.floor((tokenResponse.expiresOnTimestamp - Date.now()) / 1000),
        };
    };
    
  3. Set your cluster name variable to connect to your Azure Cosmos DB for MongoDB vCore cluster.

    const clusterName = '<azure-cosmos-db-mongodb-vcore-cluster-name>';
    
  4. Create an instance of DefaultAzureCredential.

    const credential = new DefaultAzureCredential();
    
  5. Create a MongoDB client configured with OpenID Connect (OIDC) authentication.

    client = new MongoClient(`mongodb+srv://${clusterName}.global.mongocluster.cosmos.azure.com/`, {
        connectTimeoutMS: 120000,
        tls: true,
        retryWrites: true,
        authMechanism: 'MONGODB-OIDC',
        authMechanismProperties: {
            OIDC_CALLBACK: (params) => azureIdentityTokenCallback(params, credential),
            ALLOWED_HOSTS: ['*.azure.com']
        }
    });
    
    console.log('Client created');
    
  1. Import the necessary modules at the top of your TypeScript file.

    import { AccessToken, DefaultAzureCredential, TokenCredential } from '@azure/identity';
    import { Collection, Db, Filter, FindCursor, MongoClient, OIDCCallbackParams, OIDCResponse, UpdateFilter, UpdateOptions, UpdateResult, WithId } from 'mongodb';
    
  2. Create a token callback function that obtains tokens from the TokenCredential instance when required.

    const AzureIdentityTokenCallback = async (params: OIDCCallbackParams, credential: TokenCredential): Promise<OIDCResponse> => {
        const tokenResponse: AccessToken | null = await credential.getToken(['https://ossrdbms-aad.database.windows.net/.default']);
        return {
            accessToken: tokenResponse?.token || '',
            expiresInSeconds: (tokenResponse?.expiresOnTimestamp || 0) - Math.floor(Date.now() / 1000)
        };
    };
    
  3. Set your cluster name variable to connect to your Azure Cosmos DB for MongoDB vCore cluster.

    const clusterName: string = '<azure-cosmos-db-mongodb-vcore-cluster-name>';
    
  4. Create an instance of DefaultAzureCredential.

    const credential: TokenCredential = new DefaultAzureCredential();
    
  5. Create a MongoDB client configured with OpenID Connect (OIDC) authentication.

    const client = new MongoClient(
        `mongodb+srv://${clusterName}.global.mongocluster.cosmos.azure.com/`, {
        connectTimeoutMS: 120000,
        tls: true,
        retryWrites: true,
        authMechanism: 'MONGODB-OIDC',
        authMechanismProperties: {
            OIDC_CALLBACK: (params: OIDCCallbackParams) => AzureIdentityTokenCallback(params, credential),
            ALLOWED_HOSTS: ['*.azure.com']
        }
    });
    
    console.log('Client created');
    

Perform common operations

Finally, use the official library to perform common tasks with databases, collections, and documents. Here, you use the same classes and methods you would use to interact with MongoDB or DocumentDB to manage your collections and items.

  1. Get a reference to your database by name.

    const databaseName = process.env.SETTINGS__DATABASENAME ?? 'cosmicworks';
    
    console.log('Database pointer created');
    
  2. Get a reference to your collection.

    const collectionName = process.env.SETTINGS__COLLECTIONNAME ?? 'products';
    
    console.log('Collection pointer created');
    
  3. Create a document using collection.updateOne and upsert it into the collection.

    const filter = { _id: request.params._id };
    const payload = {
        $set: document
    };
    const options = {
        upsert: true
    };
    
    var response = await collection.updateOne(filter, payload, options);
    
    if (response.acknowledged) {
        console.log(`Documents upserted count:\t${response.matchedCount}`);
    }
    
  4. Use collection.findOne to get a specific document from the collection.

    const filter = { _id: request.params.id };
    
    var document = await collection.findOne(filter, options);
    
    console.log(`Read document _id:\t${document._id}`);
    
  5. Query for multiple documents matching a filter using collection.find.

    var filter = {
        category: 'gear-surf-surfboards'
    };
    
    var documents = collection.find(filter);
    
    for await (const document of documents) {
        console.log(`Found document:\t${JSON.stringify(document)}`);
    }
    
  6. Close the MongoDB client connection when done.

    await client.close();
    
  1. Get a reference to your database by name.

    const database: Db = client.db('<database-name>');
    
    console.log('Database pointer created');
    
  2. Get a reference to your collection.

    const collection: Collection<Product> = database.collection<Product>('<collection-name>');
    
    console.log('Collection pointer created');
    
  3. Define an interface to represent your product documents.

    interface Product {
        _id: string;
        category: string;
        name: string;
        quantity: number;
        price: number;
        clearance: boolean;
    }
    
  4. Create a document using collection.updateOne and upsert it into the collection.

    var document: Product = {
        _id: 'aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb',
        category: 'gear-surf-surfboards',
        name: 'Yamba Surfboard',
        quantity: 12,
        price: 850.00,
        clearance: false
    };
    
    var query: Filter<Product> = {
        _id: 'aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb'
    };
    var payload: UpdateFilter<Product> = {
        $set: document
    };
    var options: UpdateOptions = {
        upsert: true
    };
    var response: UpdateResult<Product> = await collection.updateOne(query, payload, options);
    
    if (response.acknowledged) {
        console.log(`Documents upserted count:\t${response.matchedCount}`);
    }
    
  5. Use collection.findOne to get a specific document from the collection.

    var query: Filter<Product> = {
        _id: 'aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb',
        category: 'gear-surf-surfboards'
    };
    
    var response: WithId<Product> | null = await collection.findOne(query);
    
    var read_item: Product = response as Product;
    
    console.log(`Read document _id:\t${read_item._id}`);
    
  6. Query for multiple documents matching a filter using collection.find.

    var query: Filter<Product> = {
        category: 'gear-surf-surfboards'
    };
    
    var response: FindCursor<WithId<Product>> = collection.find(query);
    
    for await (const document of response) {
        console.log(`Found document:\t${JSON.stringify(document)}`);
    }
    
  7. Close the MongoDB client connection when done.

    await client.close();