Modifica

Condividi tramite


Quickstart: Azure Cosmos DB for Apache Cassandra client library for Node.js

Get started with the Azure Cosmos DB for Apache Cassandra client library for Node.js to store, manage, and query unstructured data. Follow the steps in this guide to create a new account, install a Node.js client library, connect to the account, perform common operations, and query your final sample data.

API reference documentation | Library source code | Package (npm)

Prerequisites

  • An Azure subscription

    • If you don't have an Azure subscription, create a free account before you begin.
  • Node.js 22 or newer

Setting up

First, set up the account and development environment for this guide. This section walks you through the process of creating an account, getting its credentials, and then preparing your development environment.

Create an account

Start by creating an API for Apache Cassandra account. Once the account is created, create the keyspace and table resources.

  1. If you don't already have a target resource group, use the az group create command to create a new resource group in your subscription.

    az group create \
        --name "<resource-group-name>" \
        --location "<location>"
    
  2. Use the az cosmosdb create command to create a new Azure Cosmos DB for Apache Cassandra account with default settings.

    az cosmosdb create \
        --resource-group "<resource-group-name>" \
        --name "<account-name>" \
        --locations "regionName=<location>" \
        --capabilities "EnableCassandra"
    
  3. Create a new keyspace using az cosmosdb cassandra keyspace create named cosmicworks.

    az cosmosdb cassandra keyspace create \
        --resource-group "<resource-group-name>" \
        --account-name "<account-name>" \
        --name "cosmicworks"
    
  4. Create a new JSON object to represent your schema using a multi-line Bash command. Then, use the az cosmosdb cassandra table create command to create a new table named products.

    schemaJson=$(cat <<EOF
    {
      "columns": [
        {
          "name": "id",
          "type": "text"
        },
        {
          "name": "name",
          "type": "text"
        },
        {
          "name": "category",
          "type": "text"
        },
        {
          "name": "quantity",
          "type": "int"
        },
        {
          "name": "price",
          "type": "decimal"
        },
        {
          "name": "clearance",
          "type": "boolean"
        }
      ],
      "partitionKeys": [
        {
          "name": "id"
        }
      ]
    }
    EOF
    )
    
    az cosmosdb cassandra table create \
        --resource-group "<resource-group-name>" \
        --account-name "<account-name>" \
        --keyspace-name "cosmicworks" \
        --name "product" \
        --schema "$schemaJson"
    

Get credentials

Now, get the password for the client library to use to create a connection to the recently created account.

  1. Use az cosmosdb show to get the contact point and username for the account.

    az cosmosdb show \
        --resource-group "<resource-group-name>" \
        --name "<account-name>" \
        --query "{username:name,contactPoint:documentEndpoint}"
    
  2. Record the value of the contactPoint and username properties from the previous commands' output. These properties' values are the contact point and username you use later in this guide to connect to the account with the library.

  3. Use az cosmosdb keys list to get the keys for the account.

    az cosmosdb keys list \
        --resource-group "<resource-group-name>" \
        --name "<account-name>" \
        --type "keys"
    
  4. Record the value of the primaryMasterKey property from the previous commands' output. This property's value is the password you use later in this guide to connect to the account with the library.

Prepare development environment

Then, configure your development environment with a new project and the client library. This step is the last required prerequisite before moving on to the rest of this guide.

  1. Start in an empty folder.

  2. Initialize a new module.

    npm init es6 --yes
    
  3. Install the cassandra-driver package from Node Package Manager (npm).

    npm install --save cassandra-driver
    
  4. Create the index.js file.

  1. Start in an empty directory.

  2. Initialize a new module.

    npm init es6 --yes
    
  3. Install the typescript package from Node Package Manager (npm).

    npm install --save-dev typescript
    
  4. Install the tsx package from npm.

    npm install --save-dev tsx
    
  5. Install the cassandra-driver package from npm.

    npm install --save cassandra-driver
    
  6. Initialize the TypeScript project using the compiler (tsc).

    npx tsc --init --target es2017 --module es2022 --moduleResolution nodenext
    
  7. Create the index.ts file.

Object model

Description
Client Represents a specific connection to a cluster
Mapper Cassandra Query Language (CQL) client used to run queries

Code examples

Authenticate client

Start by authenticating the client using the credentials gathered earlier in this guide.

  1. Open the index.js file in your integrated development environment (IDE).

  2. Import the following types from the cassandra-driver module:

    • cassandra
    • cassandra.Client
    • cassandra.mapping.Mapper
    • cassandra.auth.PlainTextAuthProvider
    import cassandra from 'cassandra-driver';
    
    const { Client } = cassandra;
    const { Mapper } = cassandra.mapping;
    const { PlainTextAuthProvider } = cassandra.auth;
    
  3. Create string constant variables for the credentials collected earlier in this guide. Name the variables username, password, and contactPoint.

    const username = '<username>';
    const password = '<password>';
    const contactPoint = '<contact-point>';
    
  4. Create another string variable for the region where you created your Azure Cosmos DB for Apache Cassandra account. Name this variable region.

    const region = '<azure-region>';
    
  5. Create a new PlainTextAuthProvider object with the credentials specified in the previous steps.

    let authProvider = new PlainTextAuthProvider(
        username,
        password
    );
    
  6. Create a Client object using the credential and configuration variables created in the previous steps.

    let client = new Client({
        contactPoints: [`${contactPoint}:10350`],
        authProvider: authProvider,
        localDataCenter: region,
        sslOptions: {
            secureProtocol: 'TLSv1_2_method'
        },
    });
    
  7. Asynchronously connect to the cluster.

    await client.connect();
    
  8. Create a new mapper targeting the cosmicworks keyspace and product table. Name the mapper Product.

    const mapper = new Mapper(client, {
        models: {
            'Product': {
                tables: ['product'],
                keyspace: 'cosmicworks'
            }
        }
    });
    
  9. Generate a mapper instance using the forModel function and the Product mapper name.

    const productMapper = mapper.forModel('Product');
    
  1. Open the index.ts file in your integrated development environment (IDE).

  2. Import the following types from the cassandra-driver module:

    • cassandra.auth
    • cassandra.mapping
    • cassandra.types
    • cassandra.Client
    • cassandra.ClientOptions
    • cassandra.mapping.Mapper
    • cassandra.auth.PlainTextAuthProvider
    import { auth, mapping, types, Client, ClientOptions } from 'cassandra-driver';
    
    const { Mapper } = mapping;
    const { PlainTextAuthProvider } = auth;
    
  3. Create string constant variables for the credentials collected earlier in this guide. Name the variables username, password, and contactPoint.

    const username: string = '<username>';
    const password: string = '<password>';
    const contactPoint: string = '<contact-point>';
    
  4. Create another string variable for the region where you created your Azure Cosmos DB for Apache Cassandra account. Name this variable region.

    const region: string = '<azure-region>';
    
  5. Create a new PlainTextAuthProvider object with the credentials specified in the previous steps.

    let authProvider = new PlainTextAuthProvider(
        username,
        password
    );
    
  6. Create an anonymous object with options that ensures that you're using the transport layer security (TLS) 1.2 protocol.

    let sslOptions = {
        secureProtocol: 'TLSv1_2_method'
    };
    
  7. Create a ClientOptions object using the credential and configuration variables created in the previous steps.

    let clientOptions: ClientOptions = {
        contactPoints: [`${contactPoint}:10350`],
        authProvider: authProvider,
        localDataCenter: region,
        sslOptions: sslOptions
    };
    
  8. Create a Client object using the clientOptions variable in the constructor.

    let client = new Client(clientOptions);
    
  9. Asynchronously connect to the cluster.

    await client.connect();
    
  10. Create a new mapper targeting the cosmicworks keyspace and product table. Name the mapper Product.

    const mapper = new Mapper( client, {
        models: {
            'Product': {
                tables: ['product'],
                keyspace: 'cosmicworks'
            }
        }
    });
    
  11. Generate a mapper instance using the forModel function and the Product mapper name.

    const productMapper = mapper.forModel('Product');
    

Warning

Complete transport layer security (TLS) validation is disabled in this guide to simplify authentication. For production deployments, fully enable validation.

Upsert data

Next, upsert new data into a table. Upserting ensures that the data is created or replaced appropriately depending on whether the same data already exists in the table.

  1. Create a new object in a variable named product.

    const product = {
        id: 'aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb',
        name: 'Yamba Surfboard',
        category: 'gear-surf-surfboards',
        quantity: 12,
        price: 850.00,
        clearance: false
    };
    
  2. Asynchronously invoke the insert function passing in the product variable created in the previous step.

    await productMapper.insert(product);
    
  1. Define a new interface named Product with fields corresponding to the table created earlier in this guide.

    Type
    Id string
    Name string
    Category string
    Quantity int
    Price decimal
    Clearance bool
    interface Product {
        id: string;
        name: string;
        category: string;
        quantity: number;
        price: number;
        clearance: boolean;
    }
    

    Tip

    In Node.js, you can create this type in another file or create it at the end of the existing file.

  2. Create a new object of type Product. Store the object in a variable named product.

    const product: Product = {
        id: 'aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb',
        name: 'Yamba Surfboard',
        category: 'gear-surf-surfboards',
        quantity: 12,
        price: 850.00,
        clearance: false
    };
    
  3. Asynchronously invoke the insert function passing in the product variable created in the previous step.

    await productMapper.insert(product);
    

Read data

Then, read data that was previously upserted into the table.

  1. Create an anonymous object named filter. In this object, include a property named id with the same value as the product created earlier in this guide.

    const filter = {
        id: 'aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb'
    };
    
  2. Invoke the get function of the mapper passing in the filter variable. Store the result in a variable named matchedProduct.

    let matchedProduct = await productMapper.get(filter);
    
  1. Create an anonymous object named filter. In this object, include a property named id with the same value as the product created earlier in this guide.

    const filter = {
        id: 'aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb'
    };
    
  2. Invoke the get function of the mapper passing in the filter variable. Store the result in a variable named matchedProduct of type Product.

    let matchedProduct: Product = await productMapper.get(filter);
    

Query data

Finally, use a query to find all data that matches a specific filter in the table.

  1. Create a new string variable named query with a CQL query that matches items with the same category field.

    const query = `
    SELECT
        *
    FROM
        cosmicworks.product
    WHERE
        category = :category
    ALLOW FILTERING
    `;
    
  2. Create an anonymous object named params. In this object, include a property named category with the same value as the product created earlier in this guide.

    const params = {
        category: 'gear-surf-surfboards'
    };
    
  3. Asynchronously invoke the execute function passing in both the query and params variables as arguments. Store the result's rows property as a variable named matchedProducts.

    let { rows: matchedProducts } = await client.execute(query, params);
    
  4. Iterate over the query results by invoking the foreach method on the array of products.

    matchedProducts.forEach(product => {
        // Do something here with each result
    });
    
  1. Create a new string variable named query with a CQL query that matches items with the same category field.

    const query: string = `
    SELECT
        *
    FROM
        cosmicworks.product
    WHERE
        category = :category
    ALLOW FILTERING
    `;
    
  2. Create an anonymous object named params. In this object, include a property named category with the same value as the product created earlier in this guide.

    const params = {
        category: 'gear-surf-surfboards'
    };
    
  3. Asynchronously invoke the execute function passing in both the query and params variables as arguments. Store the result in a variable named result of type types.ResultSet.

    let result: types.ResultSet = await client.execute(query, params);
    
  4. Store the result's rows property as a variable named matchedProducts of type Product[].

    let matchedProducts: Product[] = result.rows;
    
  5. Iterate over the query results by invoking the foreach method on the array of products.

    matchedProducts.forEach((product: Product) => {
        // Do something here with each result
    });
    

Run the code

Run the newly created application using a terminal in your application directory.

node index.js
npx tsx index.ts

Clean up resources

When you no longer need the account, remove the account from your Azure subscription by deleting the resource.

az cosmosdb delete \
    --resource-group "<resource-group-name>" \
    --name "<account-name>"

Next step