Last active
December 13, 2021 11:06
-
-
Save sele-nap/0cf1a2f952d225a7461e6dcbb4687ef4 to your computer and use it in GitHub Desktop.
WCS quest // Express 9 - Setup an architecture
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// folder routes | |
const moviesRouter = require('./movies'); | |
const setupRoutes = (app) => { | |
app.use('/api/movies', moviesRouter); | |
}; | |
module.exports = { | |
setupRoutes, | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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, | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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