Skip to content

Instantly share code, notes, and snippets.

@sele-nap
Last active December 13, 2021 11:06
Show Gist options
  • Save sele-nap/0cf1a2f952d225a7461e6dcbb4687ef4 to your computer and use it in GitHub Desktop.
Save sele-nap/0cf1a2f952d225a7461e6dcbb4687ef4 to your computer and use it in GitHub Desktop.
WCS quest // Express 9 - Setup an architecture
// folder routes
const moviesRouter = require('./movies');
const setupRoutes = (app) => {
app.use('/api/movies', moviesRouter);
};
module.exports = {
setupRoutes,
};
// folder models
const connection = require('../db-config');
const Joi = require('joi');
const db = connection.promise();
const validate = (data, forCreation = true) => {
const presence = forCreation ? 'required' : 'optional';
return Joi.object({
title: Joi.string().max(255).presence(presence),
director: Joi.string().max(255).presence(presence),
year: Joi.number().integer().min(1888).presence(presence),
color: Joi.boolean().presence(presence),
duration: Joi.number().integer().min(1).presence(presence),
}).validate(data, { abortEarly: false }).error;
};
const findMany = ({ filters: { color, max_duration } }) => {
let sql = 'SELECT * FROM movies';
const sqlValues = [];
if (color) {
sql += ' WHERE color = ?';
sqlValues.push(color);
}
if (max_duration) {
if (color) sql += ' AND duration <= ? ;';
else sql += ' WHERE duration <= ?';
sqlValues.push(max_duration);
}
return db.query(sql, sqlValues).then(([results]) => results);
};
const findOne = (id) => {
return db
.query('SELECT * FROM movies WHERE id = ?', [id])
.then(([results]) => results[0]);
};
const create = ({ title, director, year, color, duration }) => {
return db
.query(
'INSERT INTO movies (title, director, year, color, duration) VALUES (?, ?, ?, ?, ?)',
[title, director, year, color, duration]
)
.then(([result]) => {
const id = result.insertId;
return { id, title, director, year, color, duration };
});
};
const update = (id, newAttributes) => {
return db.query('UPDATE movies SET ? WHERE id = ?', [newAttributes, id]);
};
const destroy = (id) => {
return db
.query('DELETE FROM movies WHERE id = ?', [id])
.then(([result]) => result.affectedRows !== 0);
};
module.exports = {
findMany,
findOne,
validate,
create,
update,
destroy,
};
// folder routes
const moviesRouter = require('express').Router();
const Movie = require('../models/movie');
moviesRouter.get('/', (req, res) => {
const { max_duration, color } = req.query;
Movie.findMany({ filters: { max_duration, color } })
.then((movies) => {
res.json(movies);
})
.catch((err) => {
console.log(err);
res.status(500).send('Error retrieving movies from database');
});
});
moviesRouter.get('/:id', (req, res) => {
Movie.findOne(req.params.id)
.then((movie) => {
if (movie) {
res.json(movie);
} else {
res.status(404).send('Movie not found');
}
})
.catch((err) => {
res.status(500).send('Error retrieving movie from database');
});
});
moviesRouter.post('/', (req, res) => {
const error = Movie.validate(req.body);
if (error) {
res.status(422).json({ validationErrors: error.details });
} else {
Movie.create(req.body)
.then((createdMovie) => {
res.status(201).json(createdMovie);
})
.catch((err) => {
console.error(err);
res.status(500).send('Error saving the movie');
});
}
});
moviesRouter.put('/:id', (req, res) => {
let existingMovie = null;
let validationErrors = null;
Movie.findOne(req.params.id)
.then((movie) => {
existingMovie = movie;
if (!existingMovie) return Promise.reject('RECORD_NOT_FOUND');
validationErrors = Movie.validate(req.body, false);
if (validationErrors) return Promise.reject('INVALID_DATA');
return Movie.update(req.params.id, req.body);
})
.then(() => {
res.status(200).json({ ...existingMovie, ...req.body });
})
.catch((err) => {
console.error(err);
if (err === 'RECORD_NOT_FOUND')
res.status(404).send(`Movie with id ${req.params.id} not found.`);
else if (err === 'INVALID_DATA')
res.status(422).json({ validationErrors: validationErrors.details });
else res.status(500).send('Error updating a movie.');
});
});
moviesRouter.delete('/:id', (req, res) => {
Movie.destroy(req.params.id)
.then((deleted) => {
if (deleted) res.status(200).send('🎉 Movie deleted!');
else res.status(404).send('Movie not found');
})
.catch((err) => {
console.log(err);
res.status(500).send('Error deleting a movie');
});
});
module.exports = moviesRouter;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment