💾 Database Drivers
Database drivers connect NodeBlocks services to MongoDB. They abstract connection setup and collection access for use with SDK services.
🎯 Overview
Database drivers in NodeBlocks are factory functions that create configured MongoDB connections. The SDK ships one MongoDB driver today; for custom persistence adapters, see Using a Custom DataStore.
import { drivers } from '@nodeblocks/backend-sdk';
import type { MongoClientOptions } from 'mongodb';
const { getMongoClient, withMongo } = drivers;
MongoClientOptions is imported from the mongodb package — it is not re-exported by the SDK.
📊 getMongoClient vs withMongo
| Function | Calls connect() | Authentication |
|---|---|---|
getMongoClient | No (lazy — connects on first operation) | The helper adds no credentials; use the connection string or MongoClientOptions.auth |
withMongo | Yes (eager — awaits client.connect()) | Sets auth: { username, password } on the client |
📋 Available Database Drivers
MongoDB Driver
The MongoDB driver creates a configured MongoDB database instance for use with NodeBlocks services.
getMongoClient
Creates a MongoDB Db instance with the specified connection URL and database name. This is a synchronous factory — no await is required. Does not call connect() explicitly — the MongoDB driver connects lazily on the first operation.
Parameters:
| Parameter | Type | Description |
|---|---|---|
url | string | MongoDB connection string (e.g. mongodb://localhost:27017) |
dbName | string | Database name within the MongoDB instance |
options? | MongoClientOptions | Optional client options from the mongodb package (default: { timeoutMS: 30000 }) |
Returns: Db — MongoDB database instance for performing database operations
Lifecycle note:
getMongoClientcreates an internalMongoClientbut returns only theDbreference — the client is not exposed. For multi-collection apps, prefer a shared client you manage yourself or usewithMongoper collection (as service docs demonstrate).
Usage:
import { drivers } from '@nodeblocks/backend-sdk';
const { getMongoClient } = drivers;
const db = getMongoClient(
process.env.MONGODB_URI || 'mongodb://localhost:27017',
process.env.MONGODB_DB_NAME || 'myapp'
);
// Access collections
const usersCollection = db.collection('users');
const postsCollection = db.collection('posts');
Example with Custom Options:
import { drivers } from '@nodeblocks/backend-sdk';
import type { MongoClientOptions } from 'mongodb';
const { getMongoClient } = drivers;
const db = getMongoClient(
'mongodb+srv://username:password@cluster.mongodb.net/myapp',
'myapp',
{ timeoutMS: 10000 } satisfies MongoClientOptions
);
withMongo
Curried utility for creating authenticated MongoDB connections with automatic collection access. Unlike getMongoClient, this function calls client.connect() before returning the collection.
Parameters:
| Parameter | Type | Description |
|---|---|---|
dbUrl | string | MongoDB connection URL |
dbName | string | Database name to connect to |
dbUser | string | Username for authentication |
dbPassword | string | Password for authentication |
collectionName | string | Collection name to access |
options? | MongoClientOptions | Optional client options from the mongodb package (default: { timeoutMS: 30000 }). Not part of the curried signature — pass only when all five positional arguments are supplied in a single call |
Returns: Promise<{ [collectionName]: Collection<Document> }> — Object containing the requested collection
Lifecycle note: Each fully-applied
withMongo(...)call creates a newMongoClient, awaitsconnect(), and returns only the collection — the client is not exposed for shutdown. Curried factories reuse URL/database/credentials binding only; eachawait connectToMyApp('users')still opens its own connection. For multi-collection apps, prefer a single shared client you manage yourself, or accept one connection perwithMongoinvocation.
Usage Examples:
import { drivers } from '@nodeblocks/backend-sdk';
const { withMongo } = drivers;
// Full application — get users collection
const { users } = await withMongo(
'mongodb://localhost:27017/?authSource=admin',
'myapp',
'admin',
'password',
'users'
);
// Returns: { users: Collection<Document> }
// Reusable factory — URL, database, and credentials applied once
const connectToMyApp = withMongo('mongodb://localhost:27017/?authSource=admin', 'myapp', 'admin', 'password');
const { users: usersCol } = await connectToMyApp('users');
const { orders } = await connectToMyApp('orders');
// Partial factory — URL and database only
const connectWithAuth = withMongo('mongodb://localhost:27017/?authSource=admin', 'myapp');
const { posts } = await connectWithAuth('admin', 'password', 'posts');
// With custom options (all 5 positional args + options in one call)
const { users: usersWithOptions } = await withMongo(
'mongodb://localhost:27017/?authSource=admin',
'myapp',
'admin',
'password',
'users',
{ timeoutMS: 10000 }
);
Options merge behavior:
| Behavior | Detail |
|---|---|
| Default options | { timeoutMS: 30000 } when options is omitted |
| Auth override | withMongo spreads options then sets auth: { username, password } — any auth in options is overwritten by the curried credentials |
Curried options | options is the 6th parameter and is not part of the Ramda curry chain; pass it only in a single call with all five positional args |
Error behavior:
| Outcome | Behavior |
|---|---|
| Connection succeeds | Resolves to { [collectionName]: Collection<Document> } |
client.connect() fails | Promise rejects with the connection error; db() and collection() are never called |
🔧 Using Database Drivers
With Services
Pass database collections to services through the data stores parameter:
import { services, drivers } from '@nodeblocks/backend-sdk';
const { identitiesService } = services;
const { withMongo } = drivers;
const connectToDatabase = withMongo(
'mongodb://localhost:27017/?authSource=admin',
'dev',
'user',
'password'
);
identitiesService(
{ ...(await connectToDatabase('identities')) },
{
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET!,
authSignSecret: process.env.AUTH_SIGN_SECRET!,
},
}
);
See Identity Service for full Express wiring and required data stores.
🔗 Related Documentation
- Drivers Overview — Full drivers export inventory
- Using a Custom DataStore — How to implement custom database drivers