@junwatu/griddb-client
v1.1.0-beta.1
Published
A modern TypeScript client for GridDB Web API with full CRUD operations, cloud support, and comprehensive testing
Maintainers
Readme
@junwatu/griddb-client
A comprehensive TypeScript/JavaScript client library for GridDB Web API with full CRUD operations support.
Features
- 🚀 Full CRUD Operations: Create, Read, Update, Delete with ease
- 🔄 Batch Operations: Efficient batch inserts with error handling
- 🛡️ Type Safety: Full TypeScript support with comprehensive type definitions
- 🔌 Connection Management: Automatic retry logic and connection pooling
- 🎯 SQL & TQL Support: Execute both SQL and TQL queries
- 🔧 Utility Functions: ID generation, data transformation, and more
- 📊 Container Management: Create, drop, and manage GridDB containers
- ⚡ Performance Optimized: Batching, connection reuse, and efficient transformations
Installation
npm install @junwatu/griddb-clientor
yarn add @junwatu/griddb-clientQuick Start
1. Set up environment variables
Create a .env file in your project root:
GRIDDB_WEBAPI_URL=http://localhost:8080/griddb/v2
GRIDDB_USERNAME=admin
GRIDDB_PASSWORD=admin2. Basic Usage
import { GridDB } from '@junwatu/griddb-client';
// Initialize the client
const griddb = new GridDB({
griddbWebApiUrl: process.env.GRIDDB_WEBAPI_URL!,
username: process.env.GRIDDB_USERNAME!,
password: process.env.GRIDDB_PASSWORD!
});
// Create a container
await griddb.createContainer({
containerName: 'users',
columns: [
{ name: 'id', type: 'INTEGER' },
{ name: 'name', type: 'STRING' },
{ name: 'email', type: 'STRING' },
{ name: 'created_at', type: 'TIMESTAMP' }
]
});
// Insert data
await griddb.insert({
containerName: 'users',
data: {
id: 1,
name: 'John Doe',
email: '[email protected]',
created_at: new Date()
}
});
// Query data
const users = await griddb.select({
containerName: 'users',
where: 'name = ?',
bindings: ['John Doe']
});
console.log(users);API Documentation
API Overview
| Method | Description |
|--------|-------------|
| createContainer(options) | Create a new container |
| dropContainer(name) | Drop a container |
| listContainers() | List all containers |
| containerExists(name) | Check if container exists |
| getSchema(name) | Get container schema |
| insert(options) | Insert one or more rows |
| batchInsert(name, data, batchSize) | Batch insert with error handling |
| select(options) | Query rows with conditions |
| selectOne(options) | Query a single row |
| count(name, where?, bindings?) | Count rows |
| exists(name, where, bindings?) | Check if rows exist |
| update(options) | Update rows (by rowkey or WHERE clause) |
| delete(options) | Delete rows by condition |
| truncate(name) | Delete all rows from container |
| upsert(name, data, uniqueColumns) | Insert or update |
| executeSql(stmt, bindings?) | Execute raw SELECT query |
| executeDml(stmt, bindings?) | Execute raw DML (INSERT/UPDATE/DELETE) |
| executeTql(name, query) | Execute TQL query |
Initialization
import { GridDB, GridDBConfig } from '@junwatu/griddb-client';
const config: GridDBConfig = {
griddbWebApiUrl: 'http://localhost:8080/griddb/v2',
username: 'admin',
password: 'admin',
timeout: 30000, // Optional: Request timeout in ms (default: 30000)
retryAttempts: 3, // Optional: Number of retry attempts (default: 3)
retryDelay: 1000 // Optional: Delay between retries in ms (default: 1000)
};
const griddb = new GridDB(config);Container Operations
Create Container
await griddb.createContainer({
containerName: 'my_container',
columns: [
{ name: 'id', type: 'INTEGER' },
{ name: 'data', type: 'BLOB' },
{ name: 'timestamp', type: 'TIMESTAMP' }
],
containerType: 'COLLECTION', // or 'TIME_SERIES'
rowkey: true, // First column as primary key
ifNotExists: true // Don't error if exists
});Drop Container
await griddb.dropContainer('my_container');List Containers
const containers = await griddb.listContainers();
console.log(containers); // ['users', 'products', ...]CRUD Operations
Insert
// Object-based insert (property order doesn't matter)
await griddb.insert({
containerName: 'users',
data: { name: 'Alice', email: '[email protected]', id: 1 }
});
// Multiple insert with objects
await griddb.insert({
containerName: 'users',
data: [
{ name: 'Bob', email: '[email protected]', id: 2 },
{ name: 'Charlie', email: '[email protected]', id: 3 }
]
});
// Mixed object and array data
await griddb.insert({
containerName: 'users',
data: [
{ name: 'Dave', email: '[email protected]', id: 4 },
[5, 'Eve', '[email protected]'] // Arrays must follow column order
]
});
// Batch insert with error handling
const result = await griddb.batchInsert('users', largeDataArray, 100);
console.log(`Succeeded: ${result.succeeded}, Failed: ${result.failed}`);Select
// Select all
const allUsers = await griddb.select({ containerName: 'users' });
// Select with conditions
const activeUsers = await griddb.select({
containerName: 'users',
columns: ['id', 'name', 'email'],
where: 'status = ? AND created_at > ?',
bindings: ['active', '2024-01-01'],
orderBy: 'created_at',
order: 'DESC',
limit: 10,
offset: 0
});
// Select one
const user = await griddb.selectOne({
containerName: 'users',
where: 'id = ?',
bindings: [1]
});Update
// Update by primary key (upsert via rowkey — recommended)
await griddb.update({
containerName: 'users',
data: { id: 1, name: 'Alice Updated', email: '[email protected]' }
});
// Update with WHERE clause
await griddb.update({
containerName: 'users',
data: { status: 'inactive' },
where: `last_login < '2023-01-01'`
});Note: When no
whereclause is provided, update uses the Row API (PUT) which upserts by rowkey. When awhereclause is provided, it uses SQL UPDATE via the DML endpoint. For GridDB Cloud, prefer inline values in the WHERE clause over parameterizedbindings.
Delete
// Delete by ID
await griddb.delete({
containerName: 'users',
where: 'id = 1'
});
// Delete with condition
await griddb.delete({
containerName: 'users',
where: `status = 'inactive'`
});Upsert
await griddb.upsert(
'users',
{ id: 1, name: 'Alice', email: '[email protected]' },
['id'] // Unique columns to check
);Truncate
// Delete all rows from a container
await griddb.truncate('users');Query Execution
SQL Queries (SELECT)
Use executeSql for read-only SELECT queries. This sends type: 'sql-select' to the /sql/dml/query endpoint.
const result = await griddb.executeSql(
'SELECT * FROM users WHERE age > ? ORDER BY name',
[18]
);
console.log(result.results);SQL DML Statements (INSERT, UPDATE, DELETE)
Use executeDml for data modification statements. This sends type: 'sql-update' to the /sql/update endpoint, which is required by GridDB Cloud Web API for DML operations.
// Delete with raw SQL
const result = await griddb.executeDml(
'DELETE FROM users WHERE status = ?',
['inactive']
);
console.log(result.updatedRows);
// Update with raw SQL
await griddb.executeDml(
'UPDATE users SET status = ? WHERE last_login < ?',
['inactive', '2023-01-01']
);Note: The high-level
delete(),update(), andtruncate()methods useexecuteDmlinternally. You only needexecuteDmldirectly for complex DML statements not covered by the convenience methods.
TQL Queries
const result = await griddb.executeTql(
'users',
'select * where age > 18'
);Utility Functions
ID Generation
import { IdGeneratorFactory } from '@junwatu/griddb-client';
// Random integer ID (1-10000)
const randomId = IdGeneratorFactory.random();
// UUID v4
const uuid = IdGeneratorFactory.uuid();
// Timestamp-based ID
const timestampId = IdGeneratorFactory.timestamp();
// Snowflake-like ID
const snowflakeId = IdGeneratorFactory.snowflake();
// Short alphanumeric ID
const shortId = IdGeneratorFactory.short(8);Data Transformation
import { blobToBase64, base64ToBlob } from '@junwatu/griddb-client';
// Convert Blob to base64 for storage
const base64 = await blobToBase64(imageBlob);
// Convert base64 back to Blob
const blob = base64ToBlob(base64String, 'image/jpeg');Advanced Usage
Custom Logger
const griddb = new GridDB({
config: {
griddbWebApiUrl: '...',
username: '...',
password: '...'
},
logger: {
debug: (msg, ...args) => console.debug(msg, ...args),
info: (msg, ...args) => console.info(msg, ...args),
warn: (msg, ...args) => console.warn(msg, ...args),
error: (msg, ...args) => console.error(msg, ...args)
}
});Working with BLOBs
// Store image as BLOB
const imageBuffer = await fs.readFile('image.jpg');
const base64Image = imageBuffer.toString('base64');
await griddb.insert({
containerName: 'images',
data: {
id: 1,
image_data: base64Image,
mime_type: 'image/jpeg'
}
});
// Retrieve and convert back
const result = await griddb.selectOne({
containerName: 'images',
where: 'id = ?',
bindings: [1]
});
if (result) {
const imageBlob = base64ToBlob(result.image_data, result.mime_type);
// Use imageBlob...
}Error Handling
import { GridDBError } from '@junwatu/griddb-client';
try {
await griddb.insert({
containerName: 'users',
data: { id: 1, name: 'Test' }
});
} catch (error) {
if (error instanceof GridDBError) {
console.error('GridDB Error:', error.message);
console.error('Status:', error.status);
console.error('Details:', error.details);
} else {
console.error('Unexpected error:', error);
}
}Type Definitions
The library exports all type definitions for use in your TypeScript projects:
import {
GridDBConfig,
GridDBColumn,
GridDBRow,
GridDBQuery,
ContainerType,
GridDBColumnType,
CreateOptions,
InsertOptions,
SelectOptions,
UpdateOptions,
DeleteOptions,
QueryResult,
BatchOperationResult
} from '@junwatu/griddb-client';GridDBQuery Type
interface GridDBQuery {
type: 'sql-select' | 'sql-update' | 'tql';
stmt: string;
bindings?: GridDBValue[];
}sql-select— Used for SELECT queries via/sql/dml/querysql-update— Used for DML statements (INSERT, UPDATE, DELETE) via/sql/updatetql— Used for TQL queries
GridDB Cloud
This library fully supports GridDB Cloud. GridDB Cloud's Web API strictly separates SELECT queries from DML (data modification) operations at the endpoint level:
| Operation | API Type | Endpoint |
|-----------|----------|----------|
| SELECT, COUNT | sql-select | /sql/dml/query |
| INSERT, UPDATE, DELETE | sql-update | /sql/update |
The library handles this automatically — select(), selectOne(), count() use the SELECT endpoint, while delete(), update() (with WHERE clause), and truncate() use the DML endpoint.
Tip: Make sure your IP address is added to the GridDB Cloud allowlist, otherwise all requests will return
403 Forbidden.
GridDB Cloud Configuration
const griddb = new GridDB({
griddbWebApiUrl: 'https://cloud1.griddb.com/trial1234/griddb/v2/gs_clustertrial1234/dbs/public',
username: 'your_username',
password: 'your_password'
});Environment Variables
Create a .env file with the following variables:
# GridDB Web API Configuration
GRIDDB_WEBAPI_URL=http://localhost:8080/griddb/v2
GRIDDB_USERNAME=admin
GRIDDB_PASSWORD=admin
# Optional
GRIDDB_TIMEOUT=30000
GRIDDB_RETRY_ATTEMPTS=3
GRIDDB_RETRY_DELAY=1000Development
Build
npm run buildTest
npm testLint
npm run lintFormat
npm run formatLicense
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues and questions, please use the GitHub Issues page.
