We need to implement two different approaches for loading associated data in Sequelize: eager loading and lazy loading. Our database has Bands and Musicians in a one-to-many relationship, where we need to:
The database schema shows:
Let's look at the existing implementations for single band queries:
// Lazy loading makes separate queries as needed
app.get('/bands-lazy/:id', async (req, res, next) => {
// First query - get the band
const band = await Band.findByPk(req.params.id);
// Second query - get the musicians
const bandMembers = await band.getMusicians({
order: [ ['firstName'] ]
});
const payload = {
id: band.id,
name: band.name,
createdAt: band.createdAt,
updatedAt: band.updatedAt,
Musicians: bandMembers
}
res.json(payload);
});
// Eager loading gets everything in one query
app.get('/bands-eager/:id', async (req, res, next) => {
const payload = await Band.findByPk(req.params.id, {
include: { model: Musician },
order: [ [Musician, 'firstName'] ]
});
res.json(payload);
});
Here's how we implement lazy loading for all bands:
app.get('/bands-lazy', async (req, res, next) => {
// Get all bands first
const allBands = await Band.findAll({
order: [ ['name'] ]
});
const payload = [];
for(let i = 0; i < allBands.length; i++) {
const band = allBands[i];
// Get musicians for each band separately
const musicians = await band.getMusicians({
order: [['firstName']]
});
const bandData = {
id: band.id,
name: band.name,
createdAt: band.createdAt,
updatedAt: band.updatedAt,
Musicians: musicians
};
payload.push(bandData);
}
res.json(payload);
});
Here's the eager loading implementation:
app.get('/bands-eager', async (req, res, next) => {
const payload = await Band.findAll({
include: { model: Musician },
order: [
['name'],
[Musician, 'firstName']
]
});
res.json(payload);
});
Think of lazy loading vs eager loading like shopping at a grocery store:
Let's compare both approaches:
To deepen your understanding, try these exercises:
Watch out for these common issues: