next-mongo-connector
v1.0.0
Published
A modern, secure MongoDB connector for serverless Next.js apps — built with enterprise-grade security, smart caching, pooling, graceful shutdown handling, and full TypeScript support. Maximum security against hijacking and hacking attempts.
Maintainers
Readme
Next MongoDB Connector
🚀 A production-ready, secure MongoDB connector for serverless Next.js applications
A modern, secure MongoDB connector library designed specifically for serverless Next.js environments (Vercel, AWS Lambda, etc.). Features intelligent connection caching, enterprise-grade security, full TypeScript support, and protection against common database vulnerabilities.
📋 Table of Contents
- ✨ Features
- 🚦 Quick Start
- 🎯 Advanced Usage
- 🛡️ Security Features
- 📊 API Reference
- 🔧 Configuration Options
- 🧪 Testing
- 🔧 Optional Dependencies
- 🤝 Contributing
- 📝 License
- 🔗 Links
- 🙏 Acknowledgments
✨ Features
- 🔒 Enterprise-grade Security - Anti-hijacking, injection prevention, SSL/TLS enforcement
- ⚡ Smart Connection Caching - Prevents connection storms in serverless environments
- 🛡️ Lambda-Safe - Optimized for serverless functions with graceful shutdown handling
- 📝 TypeScript First - Full type safety with comprehensive
.d.tsfiles - 🔄 Auto-Retry Logic - Configurable retry mechanisms with exponential backoff
- 🌐 Multi-Database Support - Handle multiple database connections simultaneously
- 📊 Health Monitoring - Built-in health checks and connection pool statistics
- 🎯 Next.js Optimized - Works seamlessly with both Pages and App Router
- 🚫 Zero Dependencies - Only peer dependency on Mongoose
- ⚙️ Environment Validation - Automatic URI validation and security checking
- 🔍 Advanced Connection Verification - Detailed connection status checking
- 🛠️ Model Management - Smart model compilation and caching
- 🧪 Comprehensive Testing - Full test suite with real database operations
🚦 Quick Start
Installation
npm install next-mongo-connector mongoose
# or
yarn add next-mongo-connector mongoose
# or
pnpm add next-mongo-connector mongooseEnvironment Setup
# .env.local
MONGODB_URI=mongodb+srv://username:[email protected]/database?retryWrites=true&w=majorityNext.js Configuration
Create or update your next.config.js (or next.config.ts):
import { createNextConfig } from "next-mongo-connector";
// The createNextConfig function handles all MongoDB-related
// webpack configuration automatically
const config = createNextConfig({
// Your other Next.js config options
reactStrictMode: true,
poweredByHeader: false,
});
export default config;This configuration automatically handles:
- Native MongoDB dependencies (kerberos, bson-ext, etc.)
- Binary module loading (.node files)
- Optional dependency resolution
- Webpack warning suppression
Basic Usage
import { connectMongo, getDb } from "next-mongo-connector";
// API Route (Pages Router)
export default async function handler(req, res) {
try {
// Connect to MongoDB (cached automatically)
await connectMongo();
// Get database instance
const db = getDb();
// Use the database
const users = await db.collection("users").find({}).toArray();
res.status(200).json({ users });
} catch (error) {
res.status(500).json({ error: "Database connection failed" });
}
}// App Router (app/api/users/route.ts)
import { connectMongo, getDb } from "next-mongo-connector";
export async function GET() {
try {
await connectMongo();
const db = getDb();
const users = await db.collection("users").find({}).toArray();
return Response.json({ users });
} catch (error) {
return Response.json(
{ error: "Database connection failed" },
{ status: 500 }
);
}
}🎯 Advanced Usage
With Mongoose Models
import { connectMongo, getConnection } from "next-mongo-connector";
import { Schema } from "mongoose";
// Define your schema
const userSchema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
createdAt: { type: Date, default: Date.now },
});
export default async function handler(req, res) {
try {
// Connect and get the connection instance
const connection = await connectMongo();
// Create or get the model (smart model management)
const User = connection.models.User || connection.model("User", userSchema);
// Use Mongoose methods
const user = await User.create({
name: "John Doe",
email: "[email protected]",
});
res.status(201).json({ user });
} catch (error) {
res.status(500).json({ error: error.message });
}
}Advanced Connection Verification
import {
connectMongo,
isConnectedWithVerification,
getConnectionInfo,
} from "next-mongo-connector";
export default async function handler(req, res) {
try {
await connectMongo();
// Get detailed connection verification
const verification = await isConnectedWithVerification();
// Get connection information
const info = getConnectionInfo();
res.status(200).json({
verification: {
isConnected: verification.isConnected,
readyState: verification.readyState,
connectionState: verification.connectionState,
details: verification.details,
},
connection: {
state: info?.state,
database: info?.database,
host: info?.host,
connectedAt: info?.connectedAt,
},
});
} catch (error) {
res.status(500).json({ error: "Connection verification failed" });
}
}With Connection Callbacks
import { connectMongo } from "next-mongo-connector";
await connectMongo(
process.env.MONGODB_URI,
{
debug: true,
maxRetries: 3,
retryDelay: 2000,
allowedHosts: ["*.mongodb.net", "localhost"],
},
// onConnect callback
async (connection, info) => {
console.log(`✅ Connected to ${info.database} at ${info.host}`);
console.log(
`🔗 Connection established in ${
Date.now() - info.connectedAt!.getTime()
}ms`
);
},
// onDisconnect callback
async (info) => {
console.log(`❌ Disconnected from ${info.connectionName}`);
},
// onError callback
async (error, info) => {
console.error(`🚨 Connection error on ${info.connectionName}:`, error);
}
);Multi-Database Support
import { connectMongo, getDb, isConnected } from "next-mongo-connector";
// Connect to multiple databases
await connectMongo(process.env.MAIN_DB_URI, {
connectionName: "main",
});
await connectMongo(process.env.ANALYTICS_DB_URI, {
connectionName: "analytics",
});
// Use different databases
const mainDb = getDb("main");
const analyticsDb = getDb("analytics");
const users = await mainDb.collection("users").find({}).toArray();
const events = await analyticsDb.collection("events").find({}).toArray();
// Check connection status
console.log("Main DB connected:", isConnected("main"));
console.log("Analytics DB connected:", isConnected("analytics"));Security Configuration
import { connectMongo, validateURI } from "next-mongo-connector";
// Validate URI before connecting
const validation = validateURI(process.env.MONGODB_URI!, ["*.mongodb.net"]);
if (!validation.isValid) {
throw new Error(`Invalid URI: ${validation.errors.join(", ")}`);
}
// Connect with security options
await connectMongo(process.env.MONGODB_URI, {
options: {
ssl: true,
tls: true,
tlsAllowInvalidCertificates: false,
tlsAllowInvalidHostnames: false,
maxPoolSize: 10,
serverSelectionTimeoutMS: 30000,
},
allowedHosts: ["*.mongodb.net", "trusted-host.com"],
validateSSL: true,
});Health Monitoring
import {
connectMongo,
healthCheck,
getPoolStats,
getConnectionInfo,
} from "next-mongo-connector";
export default async function handler(req, res) {
try {
await connectMongo();
// Perform health check
const health = await healthCheck();
// Get pool statistics
const stats = getPoolStats();
// Get connection information
const info = getConnectionInfo();
res.status(200).json({
health: {
isHealthy: health.isHealthy,
latency: health.latency,
lastPing: health.lastPing,
error: health.error,
},
pool: {
totalConnections: stats.totalConnections,
activeConnections: stats.activeConnections,
pendingConnections: stats.pendingConnections,
failedConnections: stats.failedConnections,
connectionNames: stats.connectionNames,
},
connection: {
state: info?.state,
database: info?.database,
host: info?.host,
connectedAt: info?.connectedAt,
retryCount: info?.retryCount,
},
});
} catch (error) {
res.status(500).json({ error: "Health check failed" });
}
}Graceful Shutdown
import { closeAllConnections } from "next-mongo-connector";
// Automatic shutdown handling is built-in, but you can also manually close connections
process.on("SIGTERM", async () => {
console.log("🔄 Gracefully shutting down...");
await closeAllConnections();
process.exit(0);
});🛡️ Security Features
URI Validation
- Protocol validation (only
mongodb://andmongodb+srv://) - Host whitelist support with wildcard patterns (
*.mongodb.net) - Malicious URI detection (prevents
javascript:,data:schemes) - Credential exposure warnings
- Comprehensive error messages with available connections
Connection Security
- Enforced SSL/TLS in production environments
- Certificate validation
- Hostname verification
- Protection against connection hijacking
- Connection state verification
Input Validation
- Buffer size limits to prevent memory exhaustion
- Connection pool size validation
- Parameter sanitization
- Model compilation safety
📊 API Reference
Core Functions
connectMongo(uri?, options?, onConnect?, onDisconnect?, onError?)
Establishes a cached MongoDB connection with improved error handling.
Parameters:
uri(string, optional): MongoDB URI (usesMONGODB_URIenv var if not provided)options(MongoConnectionOptions, optional): Connection configurationonConnect(function, optional): Callback executed on successful connectiononDisconnect(function, optional): Callback executed on disconnectiononError(function, optional): Callback executed on connection errors
Returns: Promise<mongoose.Connection>
getDb(connectionName?)
Gets the database instance from an active connection.
Parameters:
connectionName(string, optional): Name of the connection (default: 'default')
Returns: mongoose.Connection['db']
getConnection(connectionName?)
Gets the Mongoose connection instance.
Parameters:
connectionName(string, optional): Name of the connection (default: 'default')
Returns: mongoose.Connection
isConnected(connectionName?)
Checks if a connection is active with improved verification.
Parameters:
connectionName(string, optional): Name of the connection (default: 'default')
Returns: boolean
isConnectedWithVerification(connectionName?)
Gets detailed connection status with verification information.
Parameters:
connectionName(string, optional): Name of the connection (default: 'default')
Returns: Promise<{isConnected: boolean, readyState: number, connectionState: string, details: object}>
Monitoring Functions
healthCheck(connectionName?)
Performs a health check on the connection with detailed error messages.
Returns: Promise<HealthCheck>
getPoolStats()
Gets connection pool statistics.
Returns: PoolStats
getConnectionInfo(connectionName?)
Gets detailed connection information.
Returns: ConnectionInfo | null
Management Functions
closeConnection(connectionName?)
Closes a specific connection.
closeAllConnections()
Closes all active connections.
Security Functions
validateURI(uri, allowedHosts?)
Validates a MongoDB URI for security issues with comprehensive error reporting.
validateOptions(options)
Validates connection options for security compliance.
🔧 Configuration Options
MongoConnectionOptions
interface MongoConnectionOptions {
options?: mongoose.ConnectOptions; // Mongoose connection options
dbName?: string; // Database name override
debug?: boolean; // Enable debug logging
connectionTimeout?: number; // Connection timeout (ms)
maxRetries?: number; // Maximum retry attempts
retryDelay?: number; // Delay between retries (ms)
validateSSL?: boolean; // Enable SSL validation
allowedHosts?: string[]; // Whitelist of allowed hosts
connectionName?: string; // Custom connection identifier
}Environment Variables
MONGODB_URIorMONGO_URI: MongoDB connection stringNODE_ENV: Environment mode (affects security defaults)
🧪 Testing
The package includes a comprehensive test suite that validates all functionality:
Test Categories
- Connection Tests: Basic connection, health checks, multi-connection
- Security Tests: URI validation, host whitelisting, SSL enforcement
- Database Operations: CRUD operations, aggregation, model management
- Error Handling: Connection failures, validation errors, timeouts
Running Tests
# Run mocked tests
npm test
# Run integration tests (requires MongoDB)
MONGODB_URI=your_test_db_uri npm run test:integration
# Run all tests
npm run test:all
# Run with coverage
npm run test:coverageTest Suite Features
- Real database operations with sample data
- Model compilation safety testing
- Connection state verification
- Security validation testing
- Performance and reliability testing
🔧 Optional Dependencies
The package automatically handles optional MongoDB dependencies in Next.js:
kerberos- For GSSAPI authenticationaws4- For AWS IAM authenticationmongodb-client-encryption- For client-side field level encryptionsaslprep- For SCRAM authenticationsnappy- For snappy compressionbson-ext- For better BSON serialization performance@mongodb-js/zstd- For zstd compression
You don't need to install these dependencies unless you specifically need their features. The package provides empty implementations that gracefully handle their absence.
Simple Configuration
The default configuration in next.config.js handles everything automatically:
import { createNextConfig } from "next-mongo-connector";
export default createNextConfig();Custom Configuration
For advanced cases, you can customize the webpack configuration:
import { createNextConfig } from "next-mongo-connector";
export default createNextConfig({
webpack: (config, { isServer }) => {
// Add your custom webpack configuration here
return config;
},
// Other Next.js config options
});🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
🔗 Links
- npm Package
- GitHub Repository
- Issue Tracker
- Documentation
- API Reference
- Usage Examples
- Security Policy
- Contributing Guide
🙏 Acknowledgments
- Built with Mongoose
- Inspired by the Next.js community
- Security best practices from OWASP
Made with ❤️ for the Next.js community
