Apache Cassandra Node.js Driver

repository·trunk·Indexed 22 days ago

https://github.com/apache/cassandra-nodejs-driver

A feature-rich Node.js client library for Apache Cassandra, DSE, HCD, and Astra DB using the Cassandra binary protocol. Version 4.9.0 provides capabilities for managing Client instances, executing prepared statements and atomic batch operations, and implementing custom address resolution via AddressTranslator. It supports various authentication methods including PlainTextAuthProvider, DsePlainTextAuthProvider, and DseGssapiAuthProvider, as well as secure connection bundles for DataStax Astra.

Tokens
37.4K
Snippets
95
Records
218
Agent score
79%

What's inside cassandra-driver

  1. Overview of the Cassandra Driver Mapper

    trunk

    The Mapper is an object-mapping layer provided by the Cassandra Node.js driver that allows you to interact with Cassandra data as if it were a set of documents. It reduces boilerplate by using driver schema metadata instead of requiring manual schema definitions and follows convention-based mapping.

    Key features include:

    • Minimal Configuration: Automatically uses driver schema metadata.
    • Schema Flexibility: Supports denormalized schemas and materialized views by mapping a single model to multiple tables.
    • Custom Queries: Allows you to bypass automatic query generation by providing your own queries while still mapping the results to objects.
    • High Performance: Designed with minimal performance overhead compared to using the core driver directly.
  2. Overview of DataStax Node.js Driver usage samples

    trunk

    The cassandra-driver-examples repository provides practical code samples demonstrating various features of the DataStax Node.js Driver. These samples cover everything from basic connectivity to advanced features like the Object Mapper, metadata retrieval, and concurrent execution.

    Available Sample Categories

    • Basic: Connecting to a cluster and executing queries using both Promise-based and callback-based APIs.
    • Mapper: Using the Object Mapper for high-level data insertion and retrieval.
    • Metadata: Inspecting cluster information such as hosts, keyspaces, and tables.
    • Graph: Working with DSE Graph.
    • Data Types: Handling geospatial types, User-Defined Types (UDT), and Tuples.
    • Query Tracing: Retrieving traces for query requests.
    • Concurrent Execution: Techniques for inserting multiple rows from an array or executing queries in a loop with controlled concurrency levels.
  3. Explore the features of the Node.js Driver

    trunk

    The Node.js Driver for Apache Cassandra is a highly tunable client library designed for Apache Cassandra, DSE, and DataStax products. It supports a wide range of advanced capabilities including:

    • Core Connectivity: Address resolution, connection pooling, TLS/SSL, and native protocol support.
    • Query Execution: Batch statements, parameterized queries, concurrent execution API, execution profiles, and speculative query executions.
    • Data Handling: Mapping CQL data types to JavaScript types, support for User-Defined Types (UDTs), User-Defined Functions (UDFs), aggregates, and geospatial types.
    • Data Management: Paging for large result sets, row streaming, and cluster/schema metadata access.
    • Advanced Features: Object Mapper, Graph support, and integration with DataStax Astra.
    • Observability & Control: Logging, query timestamps, and query warnings.
  4. Configure Reconnection Policies

    trunk

    Reconnection policies define how the driver attempts to reconnect to nodes. The driver implements two main classes:

    • ExponentialReconnectionPolicy: The default policy, which uses an exponential backoff strategy.
    • ConstantReconnectionPolicy: Reconnects using a fixed interval.

    The policy interface relies on the #newSchedule() method to create reconnection attempts.

  5. Configure Load Balancing Policies

    trunk

    Load balancing policies determine the order of nodes (hosts) the driver uses for queries. If a node fails, the driver moves to the next node in the plan. You can choose from several implemented policies:

    • DCAwareRoundRobinPolicy: Provides round-robin queries over nodes in the local datacenter. It can include a configurable number of remote datacenter hosts, but they are only tried after local nodes.
    • RoundRobinPolicy: Yields nodes in a simple round-robin fashion.
    • TokenAwarePolicy: Yields replica nodes for a specific partition key and keyspace. It uses a child policy to provide fallback nodes if replicas are unavailable.
    • AllowListPolicy: A wrapper that only allows hosts from a specific provided list. This is primarily for testing or special cases and may interfere with the driver's host auto-detection.
    • DefaultLoadBalancingPolicy: The default policy. It yields local replicas for a given key, falling back to nodes in the local datacenter in a round-robin manner.
  6. Stream rows using eachRow() and stream()

    trunk

    For large result sets, use eachRow() or stream() to process rows as they are received without buffering the entire result set into memory.

    • eachRow(): Invokes a callback for each row as soon as it is received.
    • stream(): Returns a Readable stream in objectMode that emits Row instances. This can be piped downstream and handles automatic pause/resume logic.
    // Reducing a large result with eachRow
    client.eachRow(
      'SELECT time, val FROM temperature WHERE station_id=',
      ['abc'],
      (n, row) => {
        // The callback will be invoked per each row as soon as they are received
        minTemperature = Math.min(row.val, minTemperature); 
      },
      err => { 
        // This function will be invoked when all rows where consumed or an error was encountered  
      }
    );
    
    // Using stream()
    client.stream('SELECT time, val FROM temperature WHERE station_id=', [ 'abc' ])
      .on('readable', function () {
        // 'readable' is emitted as soon as a row is received and parsed
        let row;
        while (row = this.read()) {
          console.log('time %s and value %s', row.time, row.val);
        }
      })
      .on('end', function () {
        // Stream ended
      })
      .on('error', function (err) {
        // Error handling
      });
  7. Avoid type mismatch errors when encoding data

    trunk

    When using client.execute with parameters, the driver attempts to guess the target CQL type based on the JavaScript input type. Because JavaScript Number types are IEEE 754 doubles, they are encoded as double by default. This can cause execution failures if the target CQL column is an int or other specific integer type.

    To prevent these mismatches, use either Prepared Statements (recommended) or Parameter Hints.

  8. Use the built-in Object Mapper

    trunk

    The Object Mapper allows you to interact with Cassandra data as if they were documents. You can use methods like .find() to retrieve objects and .update() to modify them.

    // Retrieving objects
    const videos = await videoMapper.find({ userId });
    for (let video of videos) {
      console.log(video.name);
    }
    
    // Updating an object
    await videoMapper.update({ id, userId, name, addedDate, description });
  9. How address resolution works in the driver

    trunk

    The driver automatically detects new Cassandra nodes by using server-side push notifications and checking system tables. By default, the driver uses the rpc_address (or broadcast_rpc_address if defined) from the node's cassandra.yaml file as the connection address.

    In certain network topologies—such as multi-datacenter deployments where you want to use private IPs for local nodes and public IPs for remote nodes—the default addresses provided by the nodes might be unreachable or suboptimal. To handle this, you can use an AddressTranslator to transform the node's reported address into a preferred connection address.