https://github.com/questdb/nodejs-questdb-client
QuestDB Node.js Client
https://github.com/questdb/nodejs-questdb-client
async-await client-library javascript nodejs questdb questdb-ilp-client typescript
Last synced: about 5 hours ago
JSON representation
QuestDB Node.js Client
- Host: GitHub
- URL: https://github.com/questdb/nodejs-questdb-client
- Owner: questdb
- Created: 2022-07-13T14:00:50.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2024-08-20T09:03:06.000Z (10 months ago)
- Last Synced: 2025-06-25T12:50:22.130Z (2 days ago)
- Topics: async-await, client-library, javascript, nodejs, questdb, questdb-ilp-client, typescript
- Language: JavaScript
- Homepage:
- Size: 7.41 MB
- Stars: 42
- Watchers: 2
- Forks: 8
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# QuestDB Node.js Client
## Requirements
The client requires Node.js v16 or newer version.
## Installation
```shell
npm i -s @questdb/nodejs-client
```## Configuration options
Detailed description of the client's configuration options can be found in
the SenderOptions documentation.## Examples
The examples below demonstrate how to use the client.
For more details, please, check the Sender's documentation.### Basic API usage
```javascript
const { Sender } = require("@questdb/nodejs-client")async function run() {
// create a sender using HTTP protocol
const sender = Sender.fromConfig("http::addr=127.0.0.1:9000")// add rows to the buffer of the sender
await sender
.table("trades")
.symbol("symbol", "ETH-USD")
.symbol("side", "sell")
.floatColumn("price", 2615.54)
.floatColumn("amount", 0.00044)
.at(Date.now(), "ms")// flush the buffer of the sender, sending the data to QuestDB
// the buffer is cleared after the data is sent, and the sender is ready to accept new data
await sender.flush()// close the connection after all rows ingested
// unflushed data will be lost
await sender.close()
}run().then(console.log).catch(console.error)
```### Authentication and secure connection
```javascript
const { Sender } = require("@questdb/nodejs-client")async function run() {
// create a sender using HTTPS protocol with username and password authentication
const sender = Sender.fromConfig("https::addr=127.0.0.1:9000;username=admin;password=quest;")// send the data over the authenticated and secure connection
await sender
.table("trades")
.symbol("symbol", "ETH-USD")
.symbol("side", "sell")
.floatColumn("price", 2615.54)
.floatColumn("amount", 0.00044)
.at(Date.now(), "ms")
await sender.flush()// close the connection after all rows ingested
await sender.close()
}run().catch(console.error)
```### TypeScript example
```typescript
import { Sender } from "@questdb/nodejs-client"async function run(): Promise {
// create a sender using HTTPS protocol with bearer token authentication
const sender: Sender = Sender.fromConfig("https::addr=127.0.0.1:9000;token=Xyvd3er6GF87ysaHk;")// send the data over the authenticated and secure connection
await sender
.table("trades")
.symbol("symbol", "ETH-USD")
.symbol("side", "sell")
.floatColumn("price", 2615.54)
.floatColumn("amount", 0.00044)
.at(Date.now(), "ms")
await sender.flush()// close the connection after all rows ingested
await sender.close()
}run().catch(console.error);
```### Worker threads example
```javascript
const { Sender } = require("@questdb/nodejs-client")
const { Worker, isMainThread, parentPort, workerData } = require("worker_threads")// fake venue
// generates random prices and amounts for a ticker for max 5 seconds, then the feed closes
function* venue(ticker) {
let end = false
setTimeout(() => { end = true; }, rndInt(5000))
while (!end) {
yield {ticker, price: Math.random(), amount: Math.random()}
}
}// market data feed simulator
// uses the fake venue to deliver price and amount updates to the feed handler (onTick() callback)
async function subscribe(ticker, onTick) {
const feed = venue(workerData.ticker)
let tick;
while (tick = feed.next().value) {
await onTick(tick)
await sleep(rndInt(30))
}
}async function run() {
if (isMainThread) {
const tickers = ["ETH-USD", "BTC-USD", "SOL-USD", "DOGE-USD"]
// main thread to start a worker thread for each ticker
for (let ticker of tickers) {
const worker = new Worker(__filename, { workerData: { ticker: ticker } })
.on('error', (err) => { throw err; })
.on('exit', () => { console.log(`${ticker} thread exiting...`); })
.on('message', (msg) => {
console.log(`Ingested ${msg.count} prices for ticker ${msg.ticker}`)
});
}
} else {
// it is important that each worker has a dedicated sender object
// threads cannot share the sender because they would write into the same buffer
const sender = Sender.fromConfig("http::addr=127.0.0.1:9000");// subscribe for the market data of the ticker assigned to the worker
// ingest each price update into the database using the sender
let count = 0;
await subscribe(workerData.ticker, async (tick) => {
await sender
.table("trades")
.symbol("symbol", tick.ticker)
.symbol("side", "sell")
.floatColumn("price", tick.price)
.floatColumn("amount", tick.amount)
.at(Date.now(), "ms")
await sender.flush();
count++;
});// let the main thread know how many prices were ingested
parentPort.postMessage({ticker: workerData.ticker, count})// close the connection to the database
await sender.close()
}
}function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}function rndInt(limit) {
return Math.floor((Math.random() * limit) + 1)
}run()
.then(console.log)
.catch(console.error)
```## Community
If you need help, have additional questions or want to provide feedback, you
may find us on our [Community Forum](https://community.questdb.io/).You can also [sign up to our mailing list](https://questdb.io/contributors/)
to get notified of new releases.