Develop a JavaScript application with Cassandra on Azure

To create, move, or use a Cassandra DB database to Azure, you need a Cosmos DB resource. Learn how to create the resource and use your database.

Locally develop with the CosmosDB emulator

Learn how to install the CosmosDB emulator and start the emulator for Cassandra development.

Create a Cosmos DB resource for a Cassandra DB database

You can create a resource with:

Create a Cosmos DB resource for Cassandra DB

Use the following Azure CLI az cosmosdb create command in the Azure Cloud Shell to create a new resource for your Cassandra database.

az cosmosdb create \
    --subscription YOUR-SUBSCRIPTION-ID-OR-NAME \
    --resource-group YOUR-RESOURCE-GROUP \
    --name YOUR-RESOURCE_NAME \
    --capabilities EnableCassandra

This command may take a couple of minutes to complete and creates a publicly available resource. You don't need to configure firewall rules to allow your client IP address through.

The response includes your server's configuration details including:

  • location: used for the localDataCenter value in the JavaScript code with the cassandra-drive
{
  "apiProperties": null,
  "capabilities": [
    {
      "name": "EnableCassandra"
    }
  ],
  "connectorOffer": null,
  "consistencyPolicy": {
    "defaultConsistencyLevel": "Session",
    "maxIntervalInSeconds": 5,
    "maxStalenessPrefix": 100
  },
  "cors": [],
  "databaseAccountOfferType": "Standard",
  "disableKeyBasedMetadataWriteAccess": false,
  "documentEndpoint": "https://YOUR-RESOURCE_NAME.documents.azure.com:443/",
  "enableAnalyticalStorage": false,
  "enableAutomaticFailover": false,
  "enableCassandraConnector": null,
  "enableFreeTier": false,
  "enableMultipleWriteLocations": false,
  "failoverPolicies": [
    {
      "failoverPriority": 0,
      "id": "YOUR-RESOURCE_NAME-centralus",
      "locationName": "Central US"
    }
  ],
  "id": "/subscriptions/YOUR-SUBSCRIPTION-ID-OR-NAME/resourceGroups/YOUR-RESOURCE-GROUP/providers/Microsoft.DocumentDB/databaseAccounts/YOUR-RESOURCE_NAME",
  "ipRules": [],
  "isVirtualNetworkFilterEnabled": false,
  "keyVaultKeyUri": null,
  "kind": "GlobalDocumentDB",
  "location": "Central US",
  "locations": [
    {
      "documentEndpoint": "https://YOUR-RESOURCE_NAME-centralus.documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "YOUR-RESOURCE_NAME-centralus",
      "isZoneRedundant": false,
      "locationName": "Central US",
      "provisioningState": "Succeeded"
    }
  ],
  "name": "YOUR-RESOURCE_NAME",
  "privateEndpointConnections": null,
  "provisioningState": "Succeeded",
  "publicNetworkAccess": "Enabled",
  "readLocations": [
    {
      "documentEndpoint": "https://YOUR-RESOURCE_NAME-centralus.documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "YOUR-RESOURCE_NAME-centralus",
      "isZoneRedundant": false,
      "locationName": "Central US",
      "provisioningState": "Succeeded"
    }
  ],
  "resourceGroup": "YOUR-RESOURCE-GROUP",
  "systemData": {
    "createdAt": "2021-02-16T23:00:23.0375775Z"
  },
  "tags": {},
  "type": "Microsoft.DocumentDB/databaseAccounts",
  "virtualNetworkRules": [],
  "writeLocations": [
    {
      "documentEndpoint": "https://YOUR-RESOURCE_NAME-centralus.documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "YOUR-RESOURCE_NAME-centralus",
      "isZoneRedundant": false,
      "locationName": "Central US",
      "provisioningState": "Succeeded"
    }
  ]
}

Create a keyspace on the server with Azure CLI

Use the following Azure CLI az cosmosdb cassandra keyspace create command in the Azure Cloud Shell to create a new Cassandra keyspace on your server.

az cosmosdb cassandra keyspace create \
    --subscription YOUR-SUBSCRIPTION-ID-OR-NAME \
    --resource-group YOUR-RESOURCE-GROUP \
    --account-name YOUR-RESOURCE_NAME \
    --name YOUR-KEYSPACE-NAME

Create a table on the keyspace with Azure CLI

Use the following Azure CLI az cosmosdb cassandra table create command in the Azure Cloud Shell to create a new Cassandra keyspace on your server.

az cosmosdb cassandra table create \
    --subscription YOUR-SUBSCRIPTION-ID-OR-NAME \
    --resource-group YOUR-RESOURCE-GROUP \
    --account-name YOUR-RESOURCE_NAME \
    --keyspace-name YOUR-KEYSPACE-NAME \
    --name YOUR-TABLE-NAME \
    --schema @schema.json

The schema file's JSON defines the table columns, data types, and partition key:

{
    "columns": [
        {
            "name": "Name",
            "type": "Ascii"
        },
        {
            "name": "Alias",
            "type": "Ascii"
        },
        {
            "name": "Region",
            "type": "Ascii"
        }        
    ],
    "partitionKeys": [
        {
            "name": "Region"
        }
    ]
}

Get the Cassandra connection string with Azure CLI

Retrieve the MongoDB connection string for this instance with the az cosmosdb keys list command:

az cosmosdb keys list \
    --subscription YOUR-SUBSCRIPTION-ID-OR-NAME \
    --resource-group YOUR-RESOURCE-GROUP \
    --name YOUR-RESOURCE-NAME \
    --type connection-strings 

This returns your connection strings. The following JSON is an example result with the security information replaced with:

  • YOUR-RESOURCE-NAME: used for UserName and part of host name or account endpoint
  • YOUR-USERNAME: same value as YOUR-RESOURCE-NAME
  • PASSWORD-1
  • PASSWORD-2
  • ACCOUNT-KEY-1
  • ACCOUNT-KEY-2
{
    "connectionStrings": [
      {
        "connectionString": "AccountEndpoint=https://YOUR-RESOURCE-NAME.documents.azure.com:443/;AccountKey=PASSWORD-1;",
        "description": "Primary SQL Connection String"
      },
      {
        "connectionString": "AccountEndpoint=https://YOUR-RESOURCE-NAME.documents.azure.com:443/;AccountKey=PASSWORD-2;",
        "description": "Secondary SQL Connection String"
      },
      {
        "connectionString": "AccountEndpoint=https://YOUR-RESOURCE-NAME.documents.azure.com:443/;AccountKey=ACCOUNT-KEY-1;",
        "description": "Primary Read-Only SQL Connection String"
      },
      {
        "connectionString": "AccountEndpoint=https://YOUR-RESOURCE-NAME.documents.azure.com:443/;AccountKey=ACCOUNT-KEY-2;",
        "description": "Secondary Read-Only SQL Connection String"
      },
      {
        "connectionString": "HostName=YOUR-RESOURCE-NAME.cassandra.cosmos.azure.com;Username=YOUR-RESOURCE-NAME;Password=PASSWORD-1;Port=10350",
        "description": "Primary Cassandra Connection String"
      },
      {
        "connectionString": "HostName=YOUR-RESOURCE-NAME.cassandra.cosmos.azure.com;Username=YOUR-RESOURCE-NAME;Password=PASSWORD-2;Port=10350",
        "description": "Secondary Cassandra Connection String"
      },
      {
        "connectionString": "HostName=YOUR-RESOURCE-NAME.cassandra.cosmos.azure.com;Username=YOUR-RESOURCE-NAME;Password=ACCOUNT-KEY-1;Port=10350",
        "description": "Primary Read-Only Cassandra Connection String"
      },
      {
        "connectionString": "HostName=YOUR-RESOURCE-NAME.cassandra.cosmos.azure.com;Username=YOUR-RESOURCE-NAME;Password=ACCOUNT-KEY-2;Port=10350",
        "description": "Secondary Read-Only Cassandra Connection String"
      }
    ]
  }

Connect to the Cassandra database with a connection string. Your Cassandra user name is the resource name.

View and use your Cassandra DB on Azure Cosmos DB

While developing your Cassandra DB database with JavaScript, use Cosmos explorer to work with your database.

Use the Cosmos explorer, found at https://cosmos.azure.com/, to view and work with your Cassandra DB database.

The Cosmos explorer is also available in the Azure portal, for your resource, as the Data Explorer.

The Cosmos explorer is also available in the Azure portal, for your resource, as the `Data Explorer`.

Use native SDK packages to connect to Cassandra DB on Azure

The Cassandra DB database on Cosmos DB uses npm packages already available, such as:

localDataCenter using cassandra-driver:

  • V3, use the default of dataCenter1
  • V4, you must specify the data center, such as Central US in the following code block.
  let client = new cassandra.Client({
    contactPoints: [`${config.contactPoint}:10350`],
    authProvider: authProvider,
    localDataCenter: 'Central US',
    sslOptions: {
      secureProtocol: 'TLSv1_2_method',
      rejectUnauthorized: false,
    },
  });

If you are unsure of your localDataCenter, remove the property, run the sample code, and the value of the property is returned in the error text.

NoHostAvailableError: All host(s) tried for query failed. First host tried, xxx.xxx.xxx.xxx:10350: ArgumentError: localDataCenter was configured as 'dataCenter1', but only found hosts in data centers: [Central US]

Use cassandra-driver SDK to connect to Cassandra DB on Azure

To connect and use your Cassandra DB on Azure Cosmos DB with JavaScript and cassandra-driver, use the following procedure.

  1. Make sure Node.js and npm are installed.

  2. Create a Node.js project in a new folder:

    mkdir DataDemo && \
        cd DataDemo && \
        npm init -y && \
        npm install cassandra-driver && \
        touch index.js && \
        code .
    

    The command:

    • creates a project folder named DataDemo
    • changes the Bash terminal into that folder
    • initializes the project, which creates the package.json file
    • adds the cassandra-driver npm SDK to the project
    • creates the index.js script file
    • opens the project in Visual Studio Code
  3. Copy the following JavaScript code into index.js:

    // install cassandra-driver SDK
    // run at command line
    // npm install cassandra-driver
    
    const cassandra = require('cassandra-driver');
    
    const config = {
      username: 'YOUR-USERNAME', // Your Cassandra user name is the resource name 
      password:
        'YOUR-PASSWORD',
      contactPoint: 'YOUR-RESOURCE-NAME.cassandra.cosmos.azure.com',
    };
    
    let client = null;
    
    const callCassandra = async () => {
    
      // authentication 
      const authProvider = new cassandra.auth.PlainTextAuthProvider(
        config.username,
        config.password
      );
    
      // create client
      client = new cassandra.Client({
        contactPoints: [`${config.contactPoint}:10350`],
        authProvider: authProvider,
        localDataCenter: 'Central US',
        sslOptions: {
          secureProtocol: 'TLSv1_2_method',
          rejectUnauthorized: false,
        },
      });
    
      await client.connect();
      console.log("connected");
      
      // create keyspace
      let query =
        "CREATE KEYSPACE IF NOT EXISTS uprofile WITH replication = {\'class\': \'NetworkTopologyStrategy\', \'datacenter\' : \'1\' }";
      await client.execute(query);
      console.log('created keyspace');
    
      // create table
      query =
        'CREATE TABLE IF NOT EXISTS uprofile.user (name text, alias text, region text Primary Key)';
      await client.execute(query);
      console.log('created table');
    
      // insert 3 rows
      console.log('insert');
      const arr = [
        "INSERT INTO uprofile.user (name, alias , region) VALUES ('Tim Jones', 'TJones', 'centralus')",
        "INSERT INTO uprofile.user (name, alias , region) VALUES ('Joan Smith', 'JSmith', 'northus')",
        "INSERT INTO uprofile.user (name, alias , region) VALUES ('Bob Wright', 'BWright', 'westus')"
      ];
      for (const element of arr) {
        await client.execute(element);
      }
    
      // get all rows
      query = 'SELECT * FROM uprofile.user';
      const resultSelect = await client.execute(query);
    
      for (const row of resultSelect.rows) {
        console.log(
          'Obtained row: %s | %s | %s ',
          row.name,
          row.alias,
          row.region
        );
      }
    
      // get filtered row
      console.log('Getting by region');
      query = 'SELECT * FROM uprofile.user where region=\'westus\'';
      const resultSelectWhere = await client.execute(query);
    
      for (const row of resultSelectWhere.rows) {
        console.log(
          'Obtained row: %s | %s | %s ',
          row.name,
          row.alias,
          row.region
        );
      }
    
      client.shutdown();
    };
    
    callCassandra()
      .then(() => {
        console.log('done');
      })
      .catch((err) => {
        if (client) {
          client.shutdown();
        }
        console.log(err);
      });
    
  4. Replace the following in the script with your Cosmos DB Cassandra connection information:

    • YOUR-RESOURCE-NAME
    • YOUR-USERNAME - replace with YOUR-RESOURCE-NAME
    • YOUR-PASSWORD
  5. Run the script.

    node index.js
    

    The results are:

    connected
    created keyspace
    created table
    insert
    Obtained row: Joan Smith | JSmith | northus 
    Obtained row: Tim Jones | TJones | centralus 
    Obtained row: Bob Wright | BWright | westus
    Getting by region
    Obtained row: Bob Wright | BWright | westus 
    done
    

Next steps