-
PostgreSQL & Sequelize
- 2+ models, each with 2+ fields:
Web_Dev_Backend/database/models/anime.js
Lines 8 to 31 in ef7ce50
const Anime = db.define('anime', { id: { type: Sequelize.INTEGER, allowNull: false, autoIncrement: true, primaryKey: true }, title: { type: Sequelize.STRING }, genres: { type: Sequelize.ARRAY(Sequelize.STRING) }, rating: { type: Sequelize.FLOAT }, image: { type: Sequelize.STRING }, url: { type: Sequelize.STRING } }); Web_Dev_Backend/database/models/author.js
Lines 8 to 28 in ef7ce50
const Author = db.define('author', { id: { type: Sequelize.INTEGER, allowNull: false, autoIncrement: true, primaryKey: true }, // first_name: { // type: Sequelize.STRING // }, // last_name: { // type: Sequelize.STRING // }, name: { type: Sequelize.STRING }, genres: { type: Sequelize.ARRAY(Sequelize.STRING) } }); Web_Dev_Backend/database/models/manga.js
Lines 8 to 31 in ef7ce50
const Manga = db.define('manga', { id: { type: Sequelize.INTEGER, allowNull: false, autoIncrement: true, primaryKey: true }, title: { type: Sequelize.STRING }, genres: { type: Sequelize.ARRAY(Sequelize.STRING) }, rating: { type: Sequelize.FLOAT }, image: { type: Sequelize.STRING }, url: { type: Sequelize.STRING } });
- 2+ models associated with each other:
Web_Dev_Backend/database/models/index.js
Lines 5 to 8 in ef7ce50
Manga.belongsTo(Author); Author.hasMany(Manga); Anime.belongsTo(Author); Author.hasMany(Anime);
- 2+ models, each with 2+ fields:
-
API (Express, Sequelize, CRUD operations)
- Routes to add new instances to each model:
Web_Dev_Backend/routes/anime.js
Lines 57 to 74 in ef7ce50
/* HTTP POST URL: localhost:3001/anime HTTP JSON body ex: { "title": "<title>", "rating": <number>, "genres": ["item1", "item2", ...], "authorId": <id> } */ router.post('/', (req, res, next) => { Anime.create(req.body) .then(createdAnime => res.status(201).json(createdAnime)) .catch(err => next(err)); }); Web_Dev_Backend/routes/author.js
Lines 66 to 81 in ef7ce50
/* HTTP POST URL: localhost:3001/author HTTP JSON body ex: { "name": "<name>", "genres": ["item1", "item2", ...] } */ router.post('/', (req, res, next) => { Author.create(req.body) .then(createdAuthor => res.status(201).json(createdAuthor)) .catch(err => next(err)); }); Web_Dev_Backend/routes/manga.js
Lines 57 to 74 in ef7ce50
/* HTTP POST URL: localhost:3001/manga HTTP JSON body ex: { "title": "<title>", "rating": <number>, "genres": ["item1", "item2", ...], "authorId": <id> } */ router.post('/', (req, res, next) => { Manga.create(req.body) .then(createdManga => res.status(201).json(createdManga)) .catch(err => next(err)); });
- Routes that returns all instances from each model:
Web_Dev_Backend/routes/anime.js
Lines 11 to 14 in ef7ce50
router.get('/', asyncHandler(async (req, res) => { let anime = await Anime.findAll(); res.status(200).json(anime); })); Web_Dev_Backend/routes/author.js
Lines 11 to 14 in ef7ce50
router.get('/', asyncHandler(async (req, res) => { let author = await Author.findAll(); res.status(200).json(author); })); Web_Dev_Backend/routes/manga.js
Lines 11 to 14 in ef7ce50
router.get('/', asyncHandler(async (req, res) => { let manga = await Manga.findAll(); res.status(200).json(manga); }));
- Routes that return individual instances from each model based on their IDs:
Web_Dev_Backend/routes/anime.js
Lines 16 to 44 in ef7ce50
router.get('/:query', asyncHandler(async (req, res) => { // Declare object that will hold the query const queryObj = {}; // Determine the WHERE condition from the request parameters if (req.query.hasOwnProperty('id')) { queryObj.id = req.query.id; } if (req.query.hasOwnProperty('title')) { queryObj.title = req.query.title; } if(req.query.hasOwnProperty('rating')) { queryObj.rating = req.query.rating } if (req.query.hasOwnProperty('genres')) { // Array of genres let genres = req.query.genres.split(','); /* Only entries that satisfy all genres are retrieved Example of how to query for multiple genres in the HTTP request: localhost:3001/anime/query?genres=genre1,genre2,genre3 Comma separated values */ queryObj.genres = { [Sequelize.Op.contains]: genres } } Web_Dev_Backend/routes/author.js
Lines 16 to 64 in ef7ce50
/* HTTP query URL localhost:3001/author/query? Ex: localhost:3001/author/query?name=Ted */ router.get('/:query', asyncHandler(async (req, res) => { // Declare object that will hold the query const queryObj = {}; // Determine the WHERE condition from the request parameters // All these parameters are ANDed for the WHERE condition if (req.query.hasOwnProperty('id')) { queryObj.id = req.query.id; } // if (req.query.hasOwnProperty('first_name')) { // queryObj.first_name = req.query.first_name; // } // if (req.query.hasOwnProperty('last_name')) { // queryObj.last_name = req.query.last_name; // } if (req.query.hasOwnProperty('name')) { queryObj.name = req.query.name; } if (req.query.hasOwnProperty('genres')) { // Array of genres let genres = req.query.genres.split(','); /* Only entries that satisfy all genres are retrieved Example of how to query for multiple genres in the HTTP request: localhost:3001/author/query?genres=genre1,genre2,genre3 Comma separated values */ queryObj.genres = { [Sequelize.Op.contains]: genres } } // Query the Author table let author = await Author.findAll({ where: queryObj }); res.status(200).json(author); })); Web_Dev_Backend/routes/manga.js
Lines 16 to 55 in ef7ce50
router.get('/:query', asyncHandler(async (req, res) => { // Declare object that will hold the query const queryObj = {}; // Determine the WHERE condition from the request parameters if (req.query.hasOwnProperty('id')) { queryObj.id = req.query.id; } if (req.query.hasOwnProperty('title')) { queryObj.title = req.query.title; } if (req.query.hasOwnProperty('rating')) { queryObj.rating = req.query.rating; } if (req.query.hasOwnProperty('genres')) { // Array of genres let genres = req.query.genres.split(','); /* Only entries that satisfy all genres are retrieved Example of how to query for multiple genres in the HTTP request: localhost:3001/manga/query?genres=genre1,genre2,genre3 Comma separated values */ queryObj.genres = { [Sequelize.Op.contains]: genres } } // Query the Manga table let manga = await Manga.findAll({ where: queryObj, // A join to Author table, results in an "author" field // containing a JSON value with the model's fields include: [Author] }); res.status(200).json(manga); }));
- Routes that update instances in each model:
Web_Dev_Backend/routes/anime.js
Lines 76 to 100 in ef7ce50
/* HTTP PUT URL: localhost:3001/anime/ Ex: update Anime entry with id = 3 localhost:3001/anime/3 HTTP JSON body ex (update values): { "title": "<new_title_update>", "rating": <new_number_update> } */ router.put('/:id', asyncHandler(async (req, res) => { await Anime.update(req.body, { where: { id: req.params.id } }); let anime = await Anime.findByPk(req.params.id); res.status(200).json(anime); })); Web_Dev_Backend/routes/author.js
Lines 83 to 109 in ef7ce50
/* HTTP PUT URL: localhost:3001/author/ Ex: update Author entry with id = 3 localhost:3001/author/3 HTTP JSON body ex (update values): { "name": "<new_name_update>", "genres": ["<new_genre>", "<new_genre>"] } Note: genres array is overwritten not appended */ router.put('/:id', asyncHandler(async (req, res) => { await Author.update(req.body, { where: { id: req.params.id } }); let author = await Author.findByPk(req.params.id); res.status(200).json(author); })); Web_Dev_Backend/routes/manga.js
Lines 76 to 100 in ef7ce50
/* HTTP PUT URL: localhost:3001/manga/ Ex: update Manga entry with id = 3 localhost:3001/manga/3 HTTP JSON body ex (update values): { "title": "<new_title_update>", "rating": <new_number_update> } */ router.put('/:id', asyncHandler(async (req, res) => { await Manga.update(req.body, { where: { id: req.params.id } }); let manga = await Manga.findByPk(req.params.id); res.status(200).json(manga); }));
- Routes that remove instances from each model, based on their IDs:
Web_Dev_Backend/routes/anime.js
Lines 102 to 118 in ef7ce50
/* HTTP DELETE URL localhost:3001/anime/ Ex: delete Anime entry with id = 3 localhost:3001/anime/3 */ router.delete('/:id', (req, res, next) => { Anime.destroy({ where: { id: req.params.id } }) .then(() => res.status(200).json('Deleted Anime')) .catch(err => next(err)); }); Web_Dev_Backend/routes/author.js
Lines 111 to 127 in ef7ce50
/* HTTP DELETE URL localhost:3001/author/ Ex: delete Author entry with id = 3 localhost:3001/author/3 */ router.delete('/:id', (req, res, next) => { Author.destroy({ where: { id: req.params.id } }) .then(() => res.status(200).json('Deleted Author')) .catch(err => next(err)); }); Web_Dev_Backend/routes/manga.js
Lines 102 to 118 in ef7ce50
/* HTTP DELETE URL localhost:3001/manga/ Ex: delete Manga entry with id = 3 localhost:3001/manga/3 */ router.delete('/:id', (req, res, next) => { Manga.destroy({ where: { id: req.params.id } }) .then(() => res.status(200).json('Deleted Manga')) .catch(err => next(err)); });
- Route that returns an instance from a model, and all instances associated with it in a different model:
Web_Dev_Backend/routes/anime.js
Lines 46 to 52 in ef7ce50
// Query the Anime table let anime = await Anime.findAll({ where: queryObj, // A join to Author table, results in an "author" field // containing a JSON value with the model's fields include: [Author] }); Web_Dev_Backend/routes/manga.js
Lines 47 to 52 in ef7ce50
let manga = await Manga.findAll({ where: queryObj, // A join to Author table, results in an "author" field // containing a JSON value with the model's fields include: [Author] });
- Routes to add new instances to each model:
-
PostgreSQL & Sequelize
- 2+ models, each with 2+ fields:
Web_Dev_Backend/database/models/anime.js
Lines 8 to 31 in ef7ce50
Web_Dev_Backend/database/models/author.js
Lines 8 to 28 in ef7ce50
Web_Dev_Backend/database/models/manga.js
Lines 8 to 31 in ef7ce50
- 2+ models associated with each other:
Web_Dev_Backend/database/models/index.js
Lines 5 to 8 in ef7ce50
- 2+ models, each with 2+ fields:
-
API (Express, Sequelize, CRUD operations)
- Routes to add new instances to each model:
Web_Dev_Backend/routes/anime.js
Lines 57 to 74 in ef7ce50
Web_Dev_Backend/routes/author.js
Lines 66 to 81 in ef7ce50
Web_Dev_Backend/routes/manga.js
Lines 57 to 74 in ef7ce50
- Routes that returns all instances from each model:
Web_Dev_Backend/routes/anime.js
Lines 11 to 14 in ef7ce50
Web_Dev_Backend/routes/author.js
Lines 11 to 14 in ef7ce50
Web_Dev_Backend/routes/manga.js
Lines 11 to 14 in ef7ce50
- Routes that return individual instances from each model based on their IDs:
Web_Dev_Backend/routes/anime.js
Lines 16 to 44 in ef7ce50
Web_Dev_Backend/routes/author.js
Lines 16 to 64 in ef7ce50
Web_Dev_Backend/routes/manga.js
Lines 16 to 55 in ef7ce50
- Routes that update instances in each model:
Web_Dev_Backend/routes/anime.js
Lines 76 to 100 in ef7ce50
Web_Dev_Backend/routes/author.js
Lines 83 to 109 in ef7ce50
Web_Dev_Backend/routes/manga.js
Lines 76 to 100 in ef7ce50
- Routes that remove instances from each model, based on their IDs:
Web_Dev_Backend/routes/anime.js
Lines 102 to 118 in ef7ce50
Web_Dev_Backend/routes/author.js
Lines 111 to 127 in ef7ce50
Web_Dev_Backend/routes/manga.js
Lines 102 to 118 in ef7ce50
- Route that returns an instance from a model, and all instances associated with it in a different model:
Web_Dev_Backend/routes/anime.js
Lines 46 to 52 in ef7ce50
Web_Dev_Backend/routes/manga.js
Lines 47 to 52 in ef7ce50
- Routes to add new instances to each model: