TypeScript client usage

This page provides language-specific guidance for using the Data API TypeScript client.

For information about installing and getting started with the TypeScript client, see Get started with the Data API.

Client hierarchy

When you create apps using the Data API clients, you must instantiate a DataAPIClient object.

The DataAPIClient object serves as the entry point to the client hierarchy. It includes the following concepts:

Adjacent to these concepts are the administration classes for database administration. The specific administration classes you use, and how you instantiate them, depends on your client language and database type (Astra DB, HCD, or DSE).

You directly instantiate the DataAPIClient object only. Then, through the DataAPIClient object, you can instantiate and access other classes and concepts. Where necessary, instructions for instantiating other classes are provided in the command reference relevant to each class.

For instructions for instantiating the DataAPIClient object, see Instantiate a client object.

Options hierarchy

These concepts are the same for both the 1.x and 2.x versions of the TypeScript client, but specific names can change between major versions. For example, *SpawnOptions changed to *Options.

Like the client hierarchy, the options for each class also exist in a hierarchy. The general options for parent classes are deeply merged with the options for child classes.

The root of the hierarchy is the DataAPIClientOptions, which branches into AdminOptions and DbOptions. These options further branch into TableOptions and CollectionOptions, with settings merged from parent to child.

For the full list of available options at each level, see the TypeScript client reference.

TimeoutDescriptor

TimeoutDescriptor was introduced in TypeScript client version 2.0-preview. For more information about TimeoutDescriptor and migrating from 1.x timeouts to 2.x timeouts, see Client upgrade guide: Replacement of client timeout settings.

Timeout defaults

The timeoutDefaults option, of type Partial<TimeoutDescriptor>, is present throughout the options hierarchy. It represents the group of timeouts that cover any operation the client can perform, including individual and multi-call methods, as well as the time required to make the actual request call.

All timeout values are expressed in milliseconds. A timeout of 0 disables that timeout, but operations associated with that timeout setting can still follow other concurrent timeouts to limit their duration.

Most operations are subject to two different, concurrent timeouts. For example, the total duration of multi-call methods is limited by the method-specific timeout, such as generalMethodTimeoout or keyspaceAdminTimeout. Meanwhile, each underlying HTTP request is independently subject to the requestTimeout.

Per-method timeouts

For all methods that issue HTTP requests, you can override the method’s timeouts through the timeout option field.

The timeout field is always in the omnipresent options parameters, and there are two ways that you can set it:

  • Set it to a plain number, which resolves to the most appropriate timeout for the operation.

  • Set it to a subset of TimeoutDescriptor, which provides slighly more fine-grained control over the timeouts.

You can check method signatures/autocomplete to find the timeouts that are available for each method.

Timeout errors

If a timeout occurs, a DataAPITimeoutException or DevOpsAPITimeoutError is thrown, depending on the operation being performed at the time and the database type (DevOpsAPITimeoutError only occurs for Astra DB database).

To help you debug the error, the error and error message include the timeout fields that hit their defined timeout limit.

Timeout fields

Name Default Summary

requestTimeoutMs

10s

The timeout imposed on a single HTTP request.

This applies to HTTP requests to both the Data API and DevOps API, with the exception of API calls that inherently take a long time to resolve, such as createCollection.

generalMethodTimeoutMs

30s

The timeout imposed on the overall duration of a method invocation. It is valid for all DML methods that aren’t concerned with schema or admin operations.

For single-call methods, such as findOne, the client uses the lesser of generalMethodTimeoutMs and requestTimeoutMs to limit the total duration of the operation.

For methods that can take multiple HTTP calls, generalMethodTimeoutMs limits the overall duration of the method invocation, while requestTimeoutMs is separately applied to each individual HTTP request.

collectionAdminTimeoutMs

60s

A timeout imposed on all collection-related schema/admin operations, such as createCollection, listCollections, or dropCollection.

Except createCollection, each individual request issued as part of these operations must obey requestTimeoutMs in addition to collectionAdminTimeoutMs.

tableAdminTimeoutMs

30s

A timeout for all table-related schema/admin operations, such as createTable, listTables, dropTable, alter, createIndex, createVectorIndex, listIndexes, and dropTableIndex.

Each individual request issued as part of these operations must obey requestTimeoutMs in addition to tableAdminTimeoutMs.

databaseAdminTimeoutMs

10m

A timeout for all database-related schema/admin operations, such as createDatabase, listDatabases, and dropDatabase, as well as findEmbeddingProviders.

The longest running operations in this class are createDatabase and dropDatabase. If these operations are called with blocking: true, they can last several methods.

Each individual request issued as part of these operations must obey requestTimeoutMs in addition to databaseAdminTimeoutMs.

keyspaceAdminTimeoutMs

30s

A timeout for all keyspace-related operations, such as createKeyspace, listKeyspaces, and dropKeyspace.

Each individual request issued as part of these operations must obey requestTimeoutMs in addition to keyspaceAdminTimeoutMs.

FindCursor

This following information applies to TypeScript client version 2.0-preview or later.

Earlier TypeScript client versions also has a FindCursor class with similar behavior. The primary differences in FindCursor between 1.x and 2.x are as follows:

  • 2.x introduces TableFindCursor or CollectionFindCursor subclasses.

  • In 1.x, builder functions, such as skip and project, mutated the cursors in-place.

  • 2.x introduces a second TRaw type parameter on the cursor.

For more information about moving from 1.x to 2.x, see Data API client upgrade guide.

When you call a find command on a Table or a Collection, a FindCursor object is returned. FindCursor objects also have the subclassed forms TableFindCursor and CollectionFindCursor.

FindCursor objects represent a lazy stream of results that you can use to progressively retrieve new results (pagination). The basic usage pattern is to consume the cursor item by item. For example:

// Using find to create a fully-configured TableFindCursor object
const cursor = table.find<{ winner: number }>({ matchId: 'challenge6' }, {
  projection: { winner: 1 },
  limit: 3,
});

// Lazily consuming the cursor as an async iterator
for await (const item of cursor) {
  console.log(item);
}

// Or if you prefer to build the cursor using a fluent interface
// Also, you can use the toArray method to get all the results at once
const rows = await table.find({ matchId: 'challenge6' })
  .project<{ winner: number }>({ winner: 1 })
  .limit(3)
  .toArray();

console.log(rows);

Cursor properties

Cursors have the following properties that you can inspect at any time:

Name Return type Summary

state

FindCursorStatus

The current state of the cursor:

  • 'idle': Item consumption not started.

  • 'active': Item consumption in progress.

  • 'closed': All items consumed or the cursor was closed before exhaustion.

consumed

int

The number of items the cursors has yielded, meaning the number of items already read by the code consuming the cursor.

buffered

int

The number of items (documents or rows) currently stored in the client-side buffer of this cursor.

dataSource

Table | Collection

The Table or Collection instance that spawned this cursor.

This type can be more specific if a subclass of FindCursor is used.

Methods that directly alter the cursor

The following methods, in addition to iterating over the cursor, alter the cursor’s internal state:

Name Return type Summary

close

void

Closes the cursor regardless of its state.

You can close a cursor at any time. Closing a cursor discards any items that haven’t been consumed.

You can use a closed cursor again unless you call cursor.rewind().

rewind

void

Rewinds the cursor to it’s original, unconsumed state while retaining all cursor settings, such as filter, mapping, and projection.

consumeBuffer

TRaw[]

Consumes (returns) up to the requested number of raw buffered items (rows or documents).

Cursor mapping is not applied to these documents.

The returned items are consumed, meaning that the cursor can’t return those items again.

forEach

void

Consumes the remaining rows in the cursor, invoking a provided callback function on each of them.

If the callback returns exactly false, then the method stops iteration and exits early. If the method returns early, the cursor remains in the 'active' state. Otherwise, the cursor is closed.

Calling this method on a closed cursor results in an error.

toArray

T[]

Converts all remaining, unconsumed rows from the cursor into a list.

If the cursor is 'idle', the result is the entire set of rows returned by the find operation. Otherwise, the rows already consumed by the cursor aren’t in the resulting list.

DataStax doesn’t recommend calling this method if you expect a large list of results because constructing the full list requires many data exchanges with the Data API and potentially massive memory usage. If you expect many results, DataStax recommends following a lazy pattern of iterating and consuming the rows.

Calling this method on a closed cursor results in an error.

hasNext

bool

Returns a Boolean indicating whether the cursor has more documents to return.

hasNext can be called on any cursor, with the following possible outcomes:

  • If called on a closed cursor, it returns false.

  • If the current buffer is empty, it triggers the operation to fetch a new page.

  • If called on an 'idle' cursor, it fetches the first page, but the cursor stays in the 'idle' state until actual consumption starts.

getSortVector

DataAPIVector | null

Returns the query vector used in the vector (ANN) search that originated this cursor, if applicable. If the query wasn’t an ANN search or it was invoked without the includeSortVector flag, it returns null.

If called an 'idle' cursor, this method fetches the first page, but the cursor stays in the 'idle' state until actual consumption starts. If called on a closed cursor, this method returns either null or the sort vector used in the search.

Methods that copy the cursor

The following methods don’t directly alter the cursor’s internal state. Instead, these methods produce a copy of the cursor with altered attributes. You can use these to fluently build up the cursor.

Except for the clone method, these methods require that the cursor is in the 'idle' state.

Name Return type Summary

clone

FindCursor<TRaw, TRaw>

Creates a new 'idle' copy of the cursor with the same configuration except for the mapping. If the cursor had mapping, it is removed.

filter

FindCursor<T, TRaw>

Returns a copy of the cursor with a new filter setting.

project

FindCursor<RRaw, RRaw>

Return a copy of the cursor with a new projection setting.

To prevent typing misalignment, you can’t set projection if a mapping is already set.

sort

FindCursor<T, TRaw>

Returns a copy of the cursor with a new sort setting.

limit

FindCursor<T, TRaw>

Returns a copy of the cursor with a new limit setting.

includeSimilarity

FindCursor<WithSim<TRaw>, WithSim<TRaw>>

Returns a copy of the cursor with a new includeSimilarity setting.

To prevent typing misalignment, you can’t set includeSimilarity if a mapping is already set.

includeSortVector

FindCursor<T, TRaw>

Returns a copy of the cursor with a new includeSortVector setting.

skip

FindCursor

Returns a copy of the cursor with a new skip setting.

map

FindCursor

Returns a copy of the cursor with a mapping function to transform the returned items.

Calling this method on a cursor that already has a mapping causes the mapping functions to be composed.

Collection and Table typing

This information applies to TypeScript client version 2.0-preview or later. For more information, see Data API client upgrade guide.

The actual type signatures of Collection and Table aren’t standard Collection<Schema>-like types that you may be used to. Instead, they’re typed as follows:

class Collection<
  WSchema extends SomeDoc = SomeDoc,
  RSchema extends WithId<SomeDoc> = FoundDoc<WSchema>,
> {}

class Table<
  WSchema extends SomeRow,
  PKey extends SomeRow = Partial<FoundRow<WSchema>>,
  RSchema extends SomeRow = FoundRow<WSchema>,
> {}

In astra-db-ts version 1.x, FoundDoc was used in the return type of find and findOne:

async find(filter: Filter, options: FindOneOptions): FoundDoc<Schema>;

FoundDoc represents the type of the document as it’s read from the database:

  • For collections, this means an _id field is part of the type, and it won’t return $vector or $vectorize without an explicit projection.

    If you use a projection to exclude _id or include $vector or $vectorize, you must specify a specific type for the operation regardless.

  • For tables, this means vector fields are returned as DataAPIVector, regardless of the input type or use of vectorize.

For most use cases, you can treat Collection and Table as if they were Collection<Schema> and Table<Schema, Pkey?>, respectively.

Because all type parameters have default values, the usage and behavior can be the same as if they were typed simply. This means that the following is valid:

const coll = db.collection<MySchema>('my_collection');

function useCollection<T>(coll: Collection<T>) {
  // ...
}

The difference is typically negligible, with the exception of advanced use case like custom serialization/deserialization.

If necessary, such as for advanced use cases with custom serialization/deserialization logic, you can specify dual types:

type MyPKey = Pick<MyWSchema, 'ptKey' | 'clKey'>;

const coll = await db.createCollection<MyWSchema, MyRSchema>('my_collection');
const table = await db.table<MyWSchema, MyPKey, MyRSchema>('my_table');

function useCollection<W, R>(coll: Collection<W, R>) {
  // ...
}

function useTable<W, P, R>(table: Table<W, P, R>) {
  // ...
}

Custom Ser/Des

Custom ser/des is a public preview feature available in TypeScript client version 2.0-preview. Features and functionality are subject to change during the preview period.

These options are not recommended for production during the preview period.

For information about changes in 2.0-preview and migrating from 1.x to 2x, see Data API client upgrade guide.

You can use custom serialization and deserialization logic to customize client usage at a lower level, enabling features such as object mapping, custom data types, validation, snake case interop, and more.

Common options

  • mutateInPlace: Enables a minor optimization to allow any given object to be mutated in-place. This means you can serialize rows, documents, filters, sorts, and so on without creating a copy of every nested object or array.

    Only use this option if you don’t need to reuse an object after passing it to any operation. Otherwise, unexpected mutations and behaviors can occur.

  • snakeCaseInterop: Enables the client to automatically convert all keys in serialized objects to snake_case before sending them to the server, and then the client convert them back to camelCase when deserializing them.

  • codecs: You can use codecs to customize the way that objects are serialized and deserialized, allowing you to change data types, add validation logic, add object mapping, and more.

    For more information and examples, see the TypeScript client examples on GitHub.

Collection-specific options

  • enableBigNumbers: Enables serialization of bigint and BigNumber. Additionally, any number larger than the JavaScript-enforced 64-bit standard are returned as BigNumber.

Table-specific options

  • sparseData: Enables sparse returned rows. This means that any fields not present in the row are omitted from the returned row rather than being returned as null.

See also

For command specifications, see the command references, such as Work with collections, and Work with tables.

For major changes between versions, see Data API client upgrade guide.

For the complete client reference, see TypeScript client reference.

Was this helpful?

Give Feedback

How can we improve the documentation?

© 2024 DataStax | Privacy policy | Terms of use

Apache, Apache Cassandra, Cassandra, Apache Tomcat, Tomcat, Apache Lucene, Apache Solr, Apache Hadoop, Hadoop, Apache Pulsar, Pulsar, Apache Spark, Spark, Apache TinkerPop, TinkerPop, Apache Kafka and Kafka are either registered trademarks or trademarks of the Apache Software Foundation or its subsidiaries in Canada, the United States and/or other countries. Kubernetes is the registered trademark of the Linux Foundation.

General Inquiries: +1 (650) 389-6000, info@datastax.com