Connection Manager
The MongoConnectionManager is a thin singleton wrapper around a single long-lived MongoClient. The MongoDB Node driver already handles connection pooling, server monitoring, automatic reconnection and per-socket idle eviction, so the manager only adds the minimum on top: hold one client for the lifetime of the application and provide typed getDatabase / getCollection convenience methods.
An in Depth Example
This guide also has an in depth example of a working application built with Nimbus. Combining DDD, CQRS and Event Sourcing.
Check out the In Depth Example page to learn how everything is connected and works out in a real-world application.
Basic Usage
import { setupMongoConnectionManager } from "@nimbus-cqrs/mongodb";
import { getEnv } from "@nimbus-cqrs/utils";
import { ServerApiVersion } from "mongodb";
export const initMongoDB = () => {
const env = getEnv({
variables: ["MONGO_URL"],
});
setupMongoConnectionManager({
name: "default",
uri: env["MONGO_URL"],
options: {
appName: "nimbus-eventsourcing-demo",
serverApi: {
version: ServerApiVersion.v1,
strict: false,
deprecationErrors: true,
},
},
});
};
const mongoManager = getMongoConnectionManager("default");Configuration
setupMongoConnectionManager takes a MongoDB connection URI and an optional MongoClientOptions object that is forwarded as-is to the underlying MongoClient.
Optionally you can also specify a name for the connection manager. This is useful if you want to have multiple connections to different databases. If no name is specified, the connection manager will be named "default".
Refer to the MongoDB driver options reference for more information on the available options.
Use getMongoConnectionManager to get the connection manager instance.
Available Methods
| Method | Return Type | Description |
|---|---|---|
getClient() | Promise<MongoClient> | Get the connected MongoDB client (lazy-connect on first call) |
getDatabase(dbName) | Promise<Db> | Get a database instance |
getCollection(dbName, collection) | Promise<Collection> | Get a collection instance |
healthCheck() | Promise<{ status: 'healthy' | 'error'; details? }> | Ping the server to verify the connection |
close() | Promise<void> | Close the client and drain the pool (graceful shutdown) |
Connection Management
The manager creates a single MongoClient lazily on the first call to getClient() (or any of the helpers built on top of it). Concurrent first-callers share the same in-flight connect() promise, so only one connection is established. Everything beyond the initial connect() — pool growth/shrink, heartbeats, reconnects, retryable reads/writes — is delegated to the driver.
Getting Resources
// Get a connected client
const client = await getMongoConnectionManager().getClient();
// Get a database
const db = await getMongoConnectionManager().getDatabase("myDatabase");
// Get a collection (most common)
const usersCollection = await getMongoConnectionManager().getCollection(
"myDatabase",
"users"
);Health Checks
Use healthCheck() to verify the database connection:
app.get("/health", async (c) => {
const dbHealth = await getMongoConnectionManager().healthCheck();
return c.json({
status: dbHealth.status === "healthy" ? "ok" : "error",
database: dbHealth,
});
});Response format:
// Healthy
{ status: "healthy" }
// Error - `details` is the underlying error's `message`, or
// "Unknown error occurred" when no message is available.
{ status: "error", details: "<error.message>" }Graceful Shutdown
Call close() from your process shutdown handler so the driver can drain the pool cleanly:
import process from "node:process";
const shutdown = async () => {
await getMongoConnectionManager().close();
process.exit(0);
};
process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);After close() resolves, the next call to getClient() will establish a fresh connection.
Using with Repository
The connection manager integrates seamlessly with the MongoDBRepository class:
import { MongoDBRepository } from "@nimbus-cqrs/mongodb";
import { mongoManager } from "./mongodb.ts";
import { User, UserSchema } from "./user.ts";
class UserRepository extends MongoDBRepository<User> {
constructor() {
super(
() =>
getMongoConnectionManager().getCollection(
"myDatabase",
"users"
),
UserSchema,
"User"
);
}
}
export const userRepository = new UserRepository();Migration from 1.x
@nimbus-cqrs/mongodb 2.0 simplifies the connection manager. If you are upgrading from 1.x:
The constructor signature is now flattened.
FromMongoConnectionManager.getInstance(uri, { mongoClientOptions: { ... } })toMongoConnectionManager.getInstance(uri, { ... }).Use the new functions
setupMongoConnectionManagerandgetMongoConnectionManagerinstead.The
connectionTimeoutoption has been removed. The driver handles socket lifecycle viamaxIdleTimeMSon the pool.The
cleanup()method has been removed.
Delete anysetInterval(() => mongoManager.cleanup(), ...)you set up.The internal pre-flight
pingon everygetClient()call has been removed. If you relied on it for liveness, callhealthCheck()explicitly (e.g. from a/healthendpoint).A new
close()method is available for graceful shutdown.