Connecting a Node.js App to MongoDB
Wire up a complete Express + Mongoose application, from connection setup through a working REST endpoint.
Project Structure
A typical Express + Mongoose project separates concerns into models, routes, and a connection module.
src/├── models/│ └── User.js├── routes/│ └── users.js├── db.js└── server.jsEnvironment-Based Configuration
The database connection string should always come from an environment variable, never hardcoded — keeping credentials out of source control and letting the same code point to different databases per environment.
# .envMONGODB_URI=mongodb+srv://user:pass@cluster0.abcde.mongodb.net/myappA Database Connection Module
// db.jsimport mongoose from 'mongoose';
export async function connectDB() { await mongoose.connect(process.env.MONGODB_URI); console.log('MongoDB connected');}// models/User.jsimport mongoose from 'mongoose';
const userSchema = new mongoose.Schema({ name: { type: String, required: true }, email: { type: String, required: true, unique: true },});
export const User = mongoose.model('User', userSchema);A Complete REST Endpoint
// routes/users.jsimport express from 'express';import { User } from '../models/User.js';
const router = express.Router();
router.post('/users', async (req, res) => { try { const user = await User.create(req.body); res.status(201).json(user); } catch (err) { res.status(400).json({ error: err.message }); }});
router.get('/users', async (req, res) => { const users = await User.find(); res.json(users);});
export default router;// server.jsimport express from 'express';import { connectDB } from './db.js';import usersRouter from './routes/users.js';
await connectDB();
const app = express();app.use(express.json());app.use('/api', usersRouter);
app.listen(3000, () => console.log('Server running on port 3000'));Common Beginner Mistakes
Calling app.listen() before connectDB() completes can let requests through before Mongoose is ready — await the connection first, as shown above.
A validation or duplicate-key error from create() should be caught and turned into a proper 400/409 response, not left to crash the request unhandled.
FAQs
Yes — this is the standard pattern; each route/controller imports the specific models it needs from a shared models/ folder.
Mongoose's underlying driver automatically attempts to reconnect; a request in flight during a drop will typically error, which your route's error handling should catch and respond to appropriately.
Summary
A well-structured Express + Mongoose app separates models, routes, and connection setup, with configuration driven by environment variables. With application integration covered, the next section moves into advanced, production-focused MongoDB topics — starting with transactions.