AWS Aurora Serverless Data API Client
The Data API Client is a lightweight wrapper designed to simplify interactions with the Amazon Aurora Serverless Data API. It abstracts away the complexity of field values by automatically annotating native JavaScript types for input parameters and converting annotated response data back to native JavaScript types. Key features include streamlined transaction management, built-in automatic retry logic specifically optimized for Aurora Serverless scale-to-zero clusters, and compatibility layers for `pg` (node-postgres) and `mysql2/promise` drivers, enabling seamless integration with popular ORMs like Drizzle ORM and Kysely. The current stable version is 2.1.4, with active development marked by frequent minor releases addressing bug fixes, performance improvements, and new features. Version 2.0 introduced a significant migration to AWS SDK v3, full TypeScript support, and enhanced PostgreSQL data type handling, further differentiating it by offering a DocumentClient-like experience for Aurora.
Common errors
-
ENOENT: no such file or directory, open '/var/task/reserved.txt'
cause A runtime file dependency from the `pg-escape` library was not bundled correctly in AWS Lambda or similar environments.fixUpgrade `data-api-client` to version 2.1.3 or newer. This version internally implements the necessary functionality, removing the problematic external dependency. -
TypeError: (0 , data_api_client__WEBPACK_IMPORTED_MODULE_0__.default) is not a function
cause Incorrect import statement when using CommonJS or specific module interop configurations, trying to `require` a default ESM export directly without accessing the `.default` property.fixFor CommonJS, use `const DataAPIClient = require('data-api-client').default;`. For modern projects, prefer ESM `import DataAPIClient from 'data-api-client';` and ensure your environment supports ESM. -
Too many update results (or similar errors related to batch queries with RETURNING clauses on PostgreSQL)
cause The AWS RDS Data API's `BatchExecuteStatementCommand` does not correctly process `RETURNING` clauses when multiple parameter sets are provided for PostgreSQL.fixUpgrade `data-api-client` to version 2.1.4 or newer. This version detects such scenarios and executes statements individually to ensure correct `RETURNING` behavior.
Warnings
- breaking Version 2.0.0 introduced a major breaking change by migrating from AWS SDK v2 to AWS SDK v3. This reduces bundle sizes and improves Lambda cold starts but requires users to ensure their environment is compatible with AWS SDK v3 and that `@aws-sdk/client-rds-data` is at `^3.0.0`.
- gotcha Prior to v2.1.3, deployments to AWS Lambda or other bundled environments could encounter `ENOENT: no such file or directory, open '/var/task/reserved.txt'` errors. This was caused by an external `pg-escape` dependency that included runtime file dependencies not properly handled during bundling.
- gotcha PostgreSQL batch queries using a `RETURNING` clause would fail with a 'Too many update results' error in versions prior to 2.1.4. The `BatchExecuteStatementCommand` from the RDS Data API does not correctly handle `RETURNING` clauses when multiple parameter sets are provided.
- gotcha Before v2.1.2, automatic JSON parsing for PostgreSQL JSONB columns was inconsistent, specifically when the Aurora Data API returned `typeName: 'jsonb'`, which was not correctly matched for automatic deserialization.
Install
-
npm install data-api-client -
yarn add data-api-client -
pnpm add data-api-client
Imports
- DataAPIClient
const DataAPIClient = require('data-api-client');import DataAPIClient from 'data-api-client';
- createPgCompatClient
import DataAPIClient from 'data-api-client/compat/pg';
import { createPgCompatClient } from 'data-api-client/compat/pg'; - createMysql2CompatClient
import { createClient } from 'data-api-client/compat/mysql2';import { createMysql2CompatClient } from 'data-api-client/compat/mysql2';
Quickstart
import DataAPIClient from 'data-api-client';
// In a real application, these should be loaded from environment variables or a secure configuration service.
// For demonstration, using fallback values.
const config = {
secretArn: process.env.DB_SECRET_ARN ?? 'arn:aws:secretsmanager:REGION:ACCOUNT_ID:secret:DB_CREDENTIALS-XXXXX',
resourceArn: process.env.DB_RESOURCE_ARN ?? 'arn:aws:rds:REGION:ACCOUNT_ID:cluster:DB_CLUSTER_ID',
database: process.env.DB_NAME ?? 'your_database',
// Optional: configure automatic retry behavior for Aurora Serverless scale-to-zero wake-ups
retryOptions: {
maxRetries: 5,
retryDelay: (retryCount) => Math.pow(2, retryCount) * 100 // Example: exponential backoff
}
};
const db = DataAPIClient(config);
async function manageUsers() {
try {
// Insert a new user, demonstrating automatic type handling for objects (JSONB in PostgreSQL)
const insertResult = await db.query(
`INSERT INTO users (name, email, settings) VALUES (:name, :email, :settings) RETURNING id, name, settings;`,
{
name: 'John Doe',
email: 'john.doe@example.com',
settings: { theme: 'dark', notifications: true } // Auto-casts to JSONB in PostgreSQL since v2.1.2
}
);
console.log('Inserted user:', insertResult.records[0]);
// Fetch all users
const users = await db.query(`SELECT id, name, email, settings FROM users;`);
console.log('All users:', users.records);
// Update a user's name
const userId = insertResult.records[0].id;
const updateResult = await db.query(
`UPDATE users SET name = :newName WHERE id = :userId RETURNING id, name;`,
{ newName: 'Jane Doe', userId }
);
console.log('Updated user:', updateResult.records[0]);
} catch (error) {
console.error('Database operation failed:', error);
throw error;
}
}
manageUsers();