Node, Express, Sequelize, PostgreSQL, and React App Part 1 — Backend
This blog post will show you my process for creating an app using Node, Express, Sequelize, PostgreSQL, and React. Part 1 is going to focus on the backend using Node, Express, Sequelize, and PostgreSQL. This is the first time that I have used any of these languages for a backend. I will document the basics for getting the backend set up.
I am creating an app called IdeaPad that will help you keep track of any creative ideas that you have. For all of you Mac users out there, it is like combining Notes and Voice Memos together into one convenient app. For example, this will be perfect for songwriters that write lyrics and record demos of the songs that they are working on. Each individual idea will have a space to write notes and record voice memos.
Let’s get started on the backend!
Models
Ideas table
subject:string
category:string
Contents table
idea_id:integer
post:string
audio:stringAssociations
Ideas has many Contents
Content belongs to Idea
IdeaPad will be a simple app for only one user. I only need the Ideas and Contents tables with a One-To-Many Association to accomplish this. Each Idea will have many Contents that will consist of either posts or audio files.
You can follow this guide if you need help installing anything or you want more examples and explanations for what you are trying to make:
Sequelize Commands
sequelize model:create --name Idea --attributes subject:string,category:stringsequelize model:create --name Content --attributes idea_id:integer,content:string,audio:string
Sequelize Models
models/idea.js'use strict';
module.exports = (sequelize, DataTypes) => {
const Content = sequelize.define('Content', {
idea_id: DataTypes.INTEGER,
post: DataTypes.STRING,
audio: DataTypes.STRING
}, {});
Content.associate = function(models) {
Content.belongsTo(models.Idea, {
foreignKey: 'idea_id'
});
};
return Content;
};models/content.js'use strict';
module.exports = (sequelize, DataTypes) => {
const Content = sequelize.define('Content', {
idea_id: DataTypes.INTEGER,
post: DataTypes.STRING,
audio: DataTypes.STRING
}, {});
Content.associate = function(models) {
Content.belongsTo(models.Idea, {
as: 'idea',
foreignKey: 'idea_id'
});
};
return Content;
};
Node Express Controllers
controllers/idea.jsconst Idea = require('../models').Idea;
const Content = require('../models').Content;module.exports = {
list(req, res) {
return Idea
.findAll({
include: [{
model: Content,
as: 'contents'
}],
})
.then((companies) => res.status(200).send(companies))
.catch((error) => { res.status(400).send(error); });
},getById(req, res) {
return Idea
.findByPk(req.params.id, {
include: [{
model: Content,
as: 'contents'
}],
})
.then((company) => {
if (!company) {
return res.status(404).send({
message: 'Idea Not Found',
});
}
return res.status(200).send(company);
})
.catch((error) => res.status(400).send(error));
},add(req, res) {
return Idea
.create({
subject: req.body.subject,
category: req.body.category,
})
.then((company) => res.status(201).send(company))
.catch((error) => res.status(400).send(error));
},addWithContents(req, res) {
return Idea
.create({
subject: req.body.subject,
category: req.body.category,
contents: req.body.contents,
}, {
include: [{
model: Content,
as: 'contents'
}]
})
.then((company) => res.status(201).send(company))
.catch((error) => res.status(400).send(error));
},update(req, res) {
console.log(req.body);
return Idea
.findById(req.params.id, {
include: [{
model: Content,
as: 'contents'
}],
})
.then(company => {
if (!company) {
return res.status(404).send({
message: 'Idea Not Found',
});
}
return company
.updateAttributes({
subject: req.body.subject || company.subject,
category: req.body.category || company.category,
contents: req.body.contents || company.contents,
}, {
include: [{
model: Content,
as: 'contents'
}]
})
.then(() => res.status(200).send(company))
.catch((error) => {console.log(error);res.status(400).send(error);});
})
.catch((error) => {console.log(error);res.status(400).send(error);});
},delete(req, res) {
return Idea
.findByPk(req.params.id)
.then(company => {
if (!company) {
return res.status(400).send({
message: 'Idea Not Found',
});
}
return company
.destroy()
.then(() => res.status(204).send())
.catch((error) => res.status(400).send(error));
})
.catch((error) => res.status(400).send(error));
},
};controllers/content.jsconst Content = require('../models').Content;
const Idea = require('../models').Idea;module.exports = {
list(req, res) {
return Content
.findAll({
include: [{
model: Idea,
as: 'idea'
}],
})
.then((contents) => res.status(200).send(contents))
.catch((error) => { res.status(400).send(error); });
},getById(req, res) {
return Content
.findByPkv(req.params.id, {
include: [{
model: Idea,
as: 'idea'
}],
})
.then((content) => {
if (!content) {
return res.status(404).send({
message: 'Content Not Found',
});
}
return res.status(200).send(content);
})
.catch((error) => res.status(400).send(error));
},add(req, res) {
return Content
.create({
idea_id: req.body.idea_id,
post: req.body.post,
audio: req.body.audio,
})
.then((content) => res.status(201).send(content))
.catch((error) => res.status(400).send(error));
},update(req, res) {
return Content
.findById(req.params.id, {
include: [{
model: Idea,
as: 'idea'
}],
})
.then(content => {
if (!content) {
return res.status(404).send({
message: 'Content Not Found',
});
}
return content
.update({
post: req.body.post || idea.post,
audio: req.body.audio || idea.audio,
})
.then(() => res.status(200).send(content))
.catch((error) => res.status(400).send(error));
})
.catch((error) => res.status(400).send(error));
},delete(req, res) {
return Content
.findByPk(req.params.id)
.then(content => {
if (!content) {
return res.status(400).send({
message: 'Content Not Found',
});
}
return content
.destroy()
.then(() => res.status(204).send())
.catch((error) => res.status(400).send(error));
})
.catch((error) => res.status(400).send(error));
},
};controllers/index.jsconst idea = require('./idea');
const content = require('./content');module.exports = {
idea,
content,
};
Node Express Routes
routes/index.jsvar express = require('express');
var router = express.Router();const ideaController = require('../controllers').idea;
const contentController = require('../controllers').content;/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});/* Company Router */
router.get('/api/idea', ideaController.list);
router.get('/api/idea/:id', ideaController.getById);
router.post('/api/idea', ideaController.add);
router.put('/api/idea/:id', ideaController.update);
router.delete('/api/idea/:id', ideaController.delete);/* Branch Router */
router.get('/api/content', contentController.list);
router.get('/api/content/:id', contentController.getById);
router.post('/api/content', contentController.add);
router.put('/api/content/:id', contentController.update);
router.delete('/api/content/:id', contentController.delete);/* Advance Router */
router.post('/api/idea/add_with_contents', ideaController.addWithContents);module.exports = router;
Wrapping Up
Finally, we can migrate these changes with:
sequelize db:migrate
Start the server up with:
npm run start
Check if it works by going to http://localhost:3000/api/idea and http://localhost:3000/api/content in your browser.
Now we have a backend up and running!
Part 2 will be seeding the backend and creating React frontend.
Thanks for reading!