Node.js Native API

The Node.js native API supports interacting with the IoTDB table model through TableSessionPool, enabling data insertion, queries, non-query SQL, and connection management under the table model. Building on connection pool capabilities, TableSessionPool adds database context management, making it suitable for accessing relational table data in Node.js applications.

This document focuses on the usage of TableSessionPool, covering environment preparation, core steps, and common interfaces.

1. Environment Preparation

1.1 Prerequisites

  • Node.js >= 14.0.0
  • npm >= 6.0.0
  • IoTDB >= 2.0.11

1.2 Installation

  • Option 1: Install directly via npm (recommended)

Run the following command in your Node.js project:

npm install @iotdb/client
  • Option 2: Build from source

To use the development version from the repository, clone the source code and install dependencies:

git clone https://github.com/apache/iotdb-client-nodejs.git
cd iotdb-client-nodejs
git checkout develop
npm ci

On Linux, macOS, or WSL, run:

npm run build

On Windows PowerShell, run:

npm run build:esbuild
npm run build:types
New-Item -ItemType Directory -Force -Path dist\thrift\generated
Copy-Item src\thrift\generated\*.js,src\thrift\generated\*.d.ts -Destination dist\thrift\generated -Force

After the build is complete, you can install the client locally in your business project via the absolute path of the client source directory:

npm install /absolute/path/to/iotdb-client-nodejs

If you use TypeScript, no additional type declarations are required. The client comes with complete TypeScript type definitions built in.

Note: Do not use a higher-version client to connect to a lower-version server.

2. Core Steps

The three core steps of operating the IoTDB table model with the Node.js native API are as follows:

  1. Create a connection pool instance: initialize a TableSessionPool object with connection parameters, database, and pool size.
  2. Execute database operations: perform table creation, data insertion, or queries directly through the connection pool.
  3. Close the connection pool: call tablePool.close() when the program ends to release all connections.

The following sections describe the core development workflow and do not demonstrate all parameters and interfaces. For the complete capabilities, refer to the @iotdb/client source code and examples.

2.1 Creating a Connection Pool Instance

2.1.1 Single-Node Connection

import { TableSessionPool } from '@iotdb/client';

const tablePool = new TableSessionPool('localhost', 6667, {
  username: 'root',
  password: 'root',
  database: 'test',
  maxPoolSize: 10,
  minPoolSize: 2,
});

await tablePool.init();

Here database sets the default database for the table model. Once configured, the connection pool uses this database context for queries and writes.

2.1.2 Multi-Node Connection

In a cluster environment, it is recommended to configure multiple nodes with nodeUrls. The connection pool distributes connections across nodes in a round-robin manner and tries other available nodes when a connection fails.

import { TableSessionPool } from '@iotdb/client';

const tablePool = new TableSessionPool({
  nodeUrls: [
    '192.168.1.100:6667',
    '192.168.1.101:6667',
    '192.168.1.102:6667',
  ],
  username: 'root',
  password: 'root',
  database: 'test',
  maxPoolSize: 10,
  minPoolSize: 2,
});

await tablePool.init();

Connection pool parameters can be adjusted according to your workload: minPoolSize is recommended to be set to the average concurrent load, while maxPoolSize should be set to the peak concurrent load with a 20% to 30% buffer. maxIdleTime is used to clean up long-idle connections, and waitTimeout controls the maximum waiting time when the pool is exhausted. In production, it is recommended to monitor getPoolSize(), getAvailableSize(), and getInUseSize(), and adjust the pool size based on peak load.

2.1.3 SSL/TLS Connection

If SSL/TLS is enabled on the IoTDB server, you can enable SSL when creating the connection pool and specify certificate-related parameters.

import { TableSessionPool } from '@iotdb/client';
import * as fs from 'fs';

const tablePool = new TableSessionPool({
  host: 'localhost',
  port: 6667,
  username: 'root',
  password: 'root',
  database: 'test',
  enableSSL: true,
  sslOptions: {
    ca: fs.readFileSync('/path/to/ca.crt'),
    cert: fs.readFileSync('/path/to/client.crt'),
    key: fs.readFileSync('/path/to/client.key'),
    rejectUnauthorized: true,
  },
});

await tablePool.init();

2.1.4 Write Redirection

In a multi-node IoTDB cluster, the client supports write redirection. When a write operation is sent to a non-target node, the server may return a redirection hint. The client caches the target route and prefers a more suitable node for subsequent writes.

import { TableSessionPool } from '@iotdb/client';

const tablePool = new TableSessionPool({
  nodeUrls: [
    '192.168.1.100:6667',
    '192.168.1.101:6667',
    '192.168.1.102:6667',
  ],
  username: 'root',
  password: 'root',
  database: 'test',
  maxPoolSize: 10,
  enableRedirection: true,
  redirectCacheTTL: 300000,
});

await tablePool.init();

With redirection enabled, cross-node forwarding is reduced, improving write throughput and lowering network latency.

2.2 Database Operations

2.2.1 Creating a Database and a Table

await tablePool.executeNonQueryStatement('CREATE DATABASE IF NOT EXISTS test');

await tablePool.executeNonQueryStatement('USE test');

await tablePool.executeNonQueryStatement(`
  CREATE TABLE IF NOT EXISTS device_metrics (
    time TIMESTAMP TIME,
    device_id STRING TAG,
    region STRING ATTRIBUTE,
    temperature FLOAT FIELD,
    humidity FLOAT FIELD
  )
`);

2.2.2 Inserting Tablet Data

When writing in the table model, you need to specify the table name, column names, data types, timestamps, and values. The following example organizes values by column, where each array corresponds to a non-time column.

import { ColumnCategory, TSDataType } from '@iotdb/client';

await tablePool.insertTablet({
  tableName: 'device_metrics',
  columnNames: ['device_id', 'region', 'temperature', 'humidity'],
  columnTypes: [
    TSDataType.STRING,
    TSDataType.STRING,
    TSDataType.FLOAT,
    TSDataType.FLOAT,
  ],
  columnCategories: [
    ColumnCategory.TAG,
    ColumnCategory.ATTRIBUTE,
    ColumnCategory.FIELD,
    ColumnCategory.FIELD,
  ],
  timestamps: [Date.now(), Date.now() + 1000],
  values: [
    ['device_1', 'beijing', 25.5, 60.0],
    ['device_1', 'beijing', 26.0, 61.5],
  ],
});

If your project does not use the enums directly, columnTypes can also use data type codes.

For data insertion, it is recommended to use insertTablet for batch writes to reduce network round trips. A common batch size to start with is 100 to 1000 rows, then adjust based on data volume, network, and server resources.

2.2.3 Querying Data

Query results are returned through SessionDataSet. Call close() after use to release server-side query resources.

const dataSet = await tablePool.executeQueryStatement(`
  SELECT time, device_id, region, temperature, humidity
  FROM device_metrics
  WHERE device_id = 'device_1'
`);

while (await dataSet.hasNext()) {
  const row = dataSet.next();
  console.log(row.getFields());
}

await dataSet.close();

For small result sets, you can also use toArray() to load all results into memory:

const dataSet = await tablePool.executeQueryStatement('SHOW TABLES');
const rows = await dataSet.toArray();
console.log(rows);
await dataSet.close();

2.3 Closing the Connection Pool

await tablePool.close();

It is recommended to close the connection pool uniformly when the application exits, a scheduled task ends, or the service is destroyed, to avoid connection leaks.

3. Common Interfaces

3.1 TableSessionPool

3.1.1 Description

TableSessionPool is the recommended connection pool interface for the table model. It supports automatic session management and database context management. When a query, insert, or non-query method is called, the pool automatically acquires an available session and recycles the connection after execution.

3.1.2 Constructors

ConstructorDescription
new TableSessionPool(host, port, config)Traditional constructor, suitable for single-node connections
new TableSessionPool(config)Constructed with a configuration object, suitable for nodeUrls multi-node configurations
new TableSessionPool(new PoolConfigBuilder().build())Constructed with the builder pattern, recommended when there are many parameters

3.1.3 Methods

MethodDescription
init()Initializes the connection pool
close()Closes the connection pool and releases all connections
executeQueryStatement(sql, timeoutMs?)Executes a query SQL, with an optional query timeout
executeNonQueryStatement(sql)Executes a non-query SQL, such as DDL or DML
insertTablet(tablet)Inserts table model Tablet data
getPoolSize()Gets the current pool size
getAvailableSize()Gets the current number of available connections
getInUseSize()Gets the current number of connections in use

3.1.4 Configuration Options

OptionDescription
hostHost address
portPort
nodeUrlsMultiple node addresses, in the format host:port
usernameUser name
passwordPassword
databaseDefault database
timezoneTime zone
fetchSizeBatch fetch size for query results
maxPoolSizeMaximum number of connections
minPoolSizeMinimum number of connections
maxIdleTimeMaximum idle time in milliseconds
waitTimeoutWait timeout for acquiring a connection, in milliseconds
enableSSLWhether to enable SSL
sslOptionsSSL options
enableRedirectionWhether to enable write redirection
redirectCacheTTLRedirection cache expiration time in milliseconds

3.2 Tablet Parameters

The common parameters of insertTablet in the table model are as follows:

ParameterDescription
tableNameTarget table name
columnNamesList of non-time column names
dataTypesList of data types for non-time columns
columnCategoriesList of categories for non-time columns
timestampsList of timestamps
valuesList of column values, organized by column

The orders of columnNames, columnTypes, columnCategories, and values must be consistent.

4. Data Types

When inserting Tablet data, you need to specify the corresponding data type for each column. The common types supported by the Node.js client are as follows:

Type CodeType NameJavaScript TypeDescription
0BOOLEANbooleanBoolean value
1INT32number32-bit integer
2INT64bigint64-bit integer
3FLOATnumber32-bit floating point
4DOUBLEnumber64-bit floating point
5TEXTstringUTF-8 text
8TIMESTAMPDateMillisecond-precision timestamp
9DATEDateDate type
10BLOBBufferBinary data
11STRINGstringUTF-8 string

When handling the INT64 type, it is recommended to use bigint in JavaScript to avoid precision loss when values exceed the safe integer range of number.

5. FAQ

  1. Default database does not exist: If the configured database does not exist when the connection pool is initialized, first execute CREATE DATABASE, then explicitly execute USE database_name before creating tables, querying, or writing. Alternatively, create the database before initializing TableSessionPool.

  2. Column mismatch: If a column count or type mismatch occurs during insertion, check whether the orders and lengths of columnNames, columnTypes, columnCategories, and values are consistent, and confirm that values are organized by row and the table schema matches the written data.

  3. Query results consume too much memory: For large result sets, it is recommended to read in batches with hasNext() and next() and reduce fetchSize. Use toArray() only for small result sets.

  4. Connection acquisition timeout: If waiting for an available connection times out, the pool is usually exhausted. Increase waitTimeout or maxPoolSize as appropriate, and check whether there are query result sets that have not been closed for a long time.