Connecting a Database
Use a driver or ORM/ODM like Mongoose or Prisma to persist data.
Syntax
await Model.find()Express does not include a database; you choose one and connect using a library. Common options:
- Mongoose — an ODM for MongoDB, models documents as JavaScript objects.
- Prisma or Sequelize — ORMs for SQL databases like PostgreSQL and MySQL.
- Native drivers like
pgfor direct SQL.
You typically connect once at startup, then query inside your route handlers. Database calls are asynchronous, so you use async/await.
Example
const mongoose = require('mongoose');
await mongoose.connect(process.env.MONGO_URL);
const Post = mongoose.model('Post', { title: String });
app.get('/posts', async (req, res) => {
const posts = await Post.find();
res.json(posts);
});When to use it
- A developer connects Express to MongoDB using Mongoose and calls Model.find() inside a route handler to return documents as JSON.
- A team uses the pg library to run parameterised SQL queries from Express route handlers against a PostgreSQL database.
- A product API uses a repository pattern to decouple Express routes from the specific database driver, making it easy to swap databases.
More examples
MongoDB with Mongoose
Connects to MongoDB via Mongoose, defines a model, and queries all documents in an async route handler.
const mongoose = require('mongoose');
mongoose.connect(process.env.MONGO_URI);
const User = mongoose.model('User', { name: String, email: String });
app.get('/users', async (req, res, next) => {
try {
const users = await User.find();
res.json(users);
} catch (err) { next(err); }
});PostgreSQL with pg
Creates a connection pool with pg and runs a SELECT query, returning the rows array as a JSON response.
const { Pool } = require('pg');
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
app.get('/products', async (req, res, next) => {
try {
const { rows } = await pool.query('SELECT * FROM products LIMIT 50');
res.json(rows);
} catch (err) { next(err); }
});Repository pattern
Encapsulates SQL queries in a repository module so route handlers never import the database driver directly.
// repositories/userRepo.js
const pool = require('../db');
exports.findAll = () => pool.query('SELECT * FROM users').then(r => r.rows);
exports.findById = (id) => pool.query('SELECT * FROM users WHERE id=$1', [id]).then(r => r.rows[0]);
// routes/users.js
const userRepo = require('../repositories/userRepo');
app.get('/users', async (req, res, next) => { try { res.json(await userRepo.findAll()); } catch(e){ next(e); } });
app.get('/users/:id',async (req, res, next) => { try { const u = await userRepo.findById(req.params.id); u ? res.json(u) : res.status(404).json({error:'Not found'}); } catch(e){ next(e); } });
Discussion