Connecting a Database

Use a driver or ORM/ODM like Mongoose or Prisma to persist data.

Syntaxawait 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 pg for direct SQL.

You typically connect once at startup, then query inside your route handlers. Database calls are asynchronous, so you use async/await.

Example

Example · javascript
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.

Example · js
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.

Example · js
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.

Example · js
// 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

  • Be the first to comment on this lesson.