From be702f0da54676dce32588da478cdce6843acfcd Mon Sep 17 00:00:00 2001 From: Tien Nguyen Truong Date: Wed, 10 Nov 2021 09:54:16 +0700 Subject: [PATCH] update for working with frontend --- README.md | 47 ++++++--- app/config/db.config.js | 10 +- app/controllers/customer.controller.js | 116 ---------------------- app/controllers/tutorial.controller.js | 130 +++++++++++++++++++++++++ app/models/customer.model.js | 110 --------------------- app/models/tutorial.model.js | 129 ++++++++++++++++++++++++ app/routes/customer.routes.js | 21 ---- app/routes/tutorial.routes.js | 28 ++++++ package.json | 2 +- server.js | 17 +++- 10 files changed, 339 insertions(+), 271 deletions(-) delete mode 100644 app/controllers/customer.controller.js create mode 100644 app/controllers/tutorial.controller.js delete mode 100644 app/models/customer.model.js create mode 100644 app/models/tutorial.model.js delete mode 100644 app/routes/customer.routes.js create mode 100644 app/routes/tutorial.routes.js diff --git a/README.md b/README.md index 3d9e4aa..d754176 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,56 @@ # Node.js Rest APIs with Express & MySQL example For instruction, please visit: -> [Build Node.js Rest APIs with Express & MySQL](https://bezkoder.com/node-js-rest-api-express-mysql/) +> [Build Node.js Rest APIs with Express & MySQL](https://www.bezkoder.com/node-js-rest-api-express-mysql/) + +Front-end that works well with this Back-end +> [Axios Client](https://www.bezkoder.com/axios-request/) + +> [Angular 8 Client](https://www.bezkoder.com/angular-crud-app/) / [Angular 10 Client](https://www.bezkoder.com/angular-10-crud-app/) / [Angular 11 Client](https://www.bezkoder.com/angular-11-crud-app/) / [Angular 12 Client](https://www.bezkoder.com/angular-12-crud-app/) / [Angular 13 Client](https://www.bezkoder.com/angular-13-crud-example/) + +> [Vue 2 Client](https://www.bezkoder.com/vue-js-crud-app/) / [Vue 3 Client](https://www.bezkoder.com/vue-3-crud/) / [Vuetify Client](https://www.bezkoder.com/vuetify-data-table-example/) + +> [React Client](https://www.bezkoder.com/react-crud-web-api/) / [React Redux Client](https://www.bezkoder.com/react-redux-crud-example/) More Practice -> [Build Node.js Rest APIs with Express, Sequelize & MySQL](https://bezkoder.com/node-js-express-sequelize-mysql/) +> [Build Node.js Rest APIs with Express, Sequelize & MySQL](https://www.bezkoder.com/node-js-express-sequelize-mysql/) + +> [Server side Pagination in Node.js with Sequelize and MySQL](https://www.bezkoder.com/node-js-sequelize-pagination-mysql/) -> [Server side Pagination in Node.js with Sequelize and MySQL](https://bezkoder.com/node-js-sequelize-pagination-mysql/) +> [Node.js Express File Upload Rest API example](https://www.bezkoder.com/node-js-express-file-upload/) -> [Deploying/Hosting Node.js app on Heroku with MySQL database](https://bezkoder.com/deploy-node-js-app-heroku-cleardb-mysql/) +> [Node.js Express File Upload with Google Cloud Storage example](https://www.bezkoder.com/google-cloud-storage-nodejs-upload-file/) + +> [Node.js: Upload CSV file data into Database with Express](https://www.bezkoder.com/node-js-upload-csv-file-database/) + +> [Node.js: Upload Excel file data into Database with Express](https://www.bezkoder.com/node-js-upload-excel-file-database/) + +> [Deploying/Hosting Node.js app on Heroku with MySQL database](https://www.bezkoder.com/deploy-node-js-app-heroku-cleardb-mysql/) Security: -> [Node.js Express: JWT example | Token Based Authentication & Authorization](https://bezkoder.com/node-js-jwt-authentication-mysql/) +> [Node.js Express: JWT example | Token Based Authentication & Authorization](https://www.bezkoder.com/node-js-jwt-authentication-mysql/) Associations: -> [Sequelize Associations: One-to-Many Relationship example](https://bezkoder.com/sequelize-associate-one-to-many/) +> [Sequelize Associations: One-to-Many Relationship example](https://www.bezkoder.com/sequelize-associate-one-to-many/) -> [Sequelize Associations: Many-to-Many Relationship example](https://bezkoder.com/sequelize-associate-many-to-many/) +> [Sequelize Associations: Many-to-Many Relationship example](https://www.bezkoder.com/sequelize-associate-many-to-many/) Fullstack: -> [Vue.js + Node.js + Express + MySQL example](https://bezkoder.com/vue-js-node-js-express-mysql-crud-example/) +> [Vue.js + Node.js + Express + MySQL example](https://www.bezkoder.com/vue-js-node-js-express-mysql-crud-example/) + +> [Vue.js + Node.js + Express + MongoDB example](https://www.bezkoder.com/vue-node-express-mongodb-mevn-crud/) + +> [Angular 8 + Node.js + Express + MySQL example](https://www.bezkoder.com/angular-node-express-mysql/) -> [Vue.js + Node.js + Express + MongoDB example](https://bezkoder.com/vue-node-express-mongodb-mevn-crud/) +> [Angular 10 + Node.js + Express + MySQL example](https://www.bezkoder.com/angular-10-node-js-express-mysql/) -> [Angular 8 + Node.js + Express + MySQL example](https://bezkoder.com/angular-node-express-mysql/) +> [Angular 11 + Node.js Express + MySQL example](https://www.bezkoder.com/angular-11-node-js-express-mysql/) -> [Angular 10 + Node.js + Express + MySQL example](https://bezkoder.com/angular-10-node-js-express-mysql/) +> [Angular 12 + Node.js Express + MySQL example](https://www.bezkoder.com/angular-12-node-js-express-mysql/) -> [Angular 11 + Node.js Express + MySQL example](https://bezkoder.com/angular-11-node-js-express-mysql/) +> [React + Node.js + Express + MySQL example](https://www.bezkoder.com/react-node-express-mysql/) -> [React + Node.js + Express + MySQL example](https://bezkoder.com/react-node-express-mysql/) +> [React + Redux + Node.js Express + MySQL](https://www.bezkoder.com/react-redux-mysql-crud/) ## Project setup ``` diff --git a/app/config/db.config.js b/app/config/db.config.js index 02c172b..491ebb6 100644 --- a/app/config/db.config.js +++ b/app/config/db.config.js @@ -1,6 +1,6 @@ module.exports = { - HOST: "us-cdbr-iron-east-02.cleardb.net", - USER: "b7e24378878xxx", - PASSWORD: "0200exxx", - DB: "heroku_7643ec736354xxx" -}; + HOST: "localhost", + USER: "root", + PASSWORD: "123456", + DB: "testdb" +}; \ No newline at end of file diff --git a/app/controllers/customer.controller.js b/app/controllers/customer.controller.js deleted file mode 100644 index b35995d..0000000 --- a/app/controllers/customer.controller.js +++ /dev/null @@ -1,116 +0,0 @@ -const Customer = require("../models/customer.model.js"); - -// Create and Save a new Customer -exports.create = (req, res) => { - // Validate request - if (!req.body) { - res.status(400).send({ - message: "Content can not be empty!" - }); - } - - // Create a Customer - const customer = new Customer({ - email: req.body.email, - name: req.body.name, - active: req.body.active - }); - - // Save Customer in the database - Customer.create(customer, (err, data) => { - if (err) - res.status(500).send({ - message: - err.message || "Some error occurred while creating the Customer." - }); - else res.send(data); - }); -}; - -// Retrieve all Customers from the database. -exports.findAll = (req, res) => { - Customer.getAll((err, data) => { - if (err) - res.status(500).send({ - message: - err.message || "Some error occurred while retrieving customers." - }); - else res.send(data); - }); -}; - -// Find a single Customer with a customerId -exports.findOne = (req, res) => { - Customer.findById(req.params.customerId, (err, data) => { - if (err) { - if (err.kind === "not_found") { - res.status(404).send({ - message: `Not found Customer with id ${req.params.customerId}.` - }); - } else { - res.status(500).send({ - message: "Error retrieving Customer with id " + req.params.customerId - }); - } - } else res.send(data); - }); -}; - -// Update a Customer identified by the customerId in the request -exports.update = (req, res) => { - // Validate Request - if (!req.body) { - res.status(400).send({ - message: "Content can not be empty!" - }); - } - - console.log(req.body); - - Customer.updateById( - req.params.customerId, - new Customer(req.body), - (err, data) => { - if (err) { - if (err.kind === "not_found") { - res.status(404).send({ - message: `Not found Customer with id ${req.params.customerId}.` - }); - } else { - res.status(500).send({ - message: "Error updating Customer with id " + req.params.customerId - }); - } - } else res.send(data); - } - ); -}; - -// Delete a Customer with the specified customerId in the request -exports.delete = (req, res) => { - Customer.remove(req.params.customerId, (err, data) => { - if (err) { - if (err.kind === "not_found") { - res.status(404).send({ - message: `Not found Customer with id ${req.params.customerId}.` - }); - } else { - res.status(500).send({ - message: "Could not delete Customer with id " + req.params.customerId - }); - } - } else res.send({ message: `Customer was deleted successfully!` }); - }); -}; - -// Delete all Customers from the database. -exports.deleteAll = (req, res) => { - Customer.removeAll((err, data) => { - if (err) - res.status(500).send({ - message: - err.message || "Some error occurred while removing all customers." - }); - else res.send({ message: `All Customers were deleted successfully!` }); - }); -}; diff --git a/app/controllers/tutorial.controller.js b/app/controllers/tutorial.controller.js new file mode 100644 index 0000000..7da857a --- /dev/null +++ b/app/controllers/tutorial.controller.js @@ -0,0 +1,130 @@ +const Tutorial = require("../models/tutorial.model.js"); + +// Create and Save a new Tutorial +exports.create = (req, res) => { + // Validate request + if (!req.body) { + res.status(400).send({ + message: "Content can not be empty!" + }); + } + + // Create a Tutorial + const tutorial = new Tutorial({ + title: req.body.title, + description: req.body.description, + published: req.body.published || false + }); + + // Save Tutorial in the database + Tutorial.create(tutorial, (err, data) => { + if (err) + res.status(500).send({ + message: + err.message || "Some error occurred while creating the Tutorial." + }); + else res.send(data); + }); +}; + +// Retrieve all Tutorials from the database (with condition). +exports.findAll = (req, res) => { + const title = req.query.title; + + Tutorial.getAll(title, (err, data) => { + if (err) + res.status(500).send({ + message: + err.message || "Some error occurred while retrieving tutorials." + }); + else res.send(data); + }); +}; + +// Find a single Tutorial by Id +exports.findOne = (req, res) => { + Tutorial.findById(req.params.id, (err, data) => { + if (err) { + if (err.kind === "not_found") { + res.status(404).send({ + message: `Not found Tutorial with id ${req.params.id}.` + }); + } else { + res.status(500).send({ + message: "Error retrieving Tutorial with id " + req.params.id + }); + } + } else res.send(data); + }); +}; + +// find all published Tutorials +exports.findAllPublished = (req, res) => { + Tutorial.getAllPublished((err, data) => { + if (err) + res.status(500).send({ + message: + err.message || "Some error occurred while retrieving tutorials." + }); + else res.send(data); + }); +}; + +// Update a Tutorial identified by the id in the request +exports.update = (req, res) => { + // Validate Request + if (!req.body) { + res.status(400).send({ + message: "Content can not be empty!" + }); + } + + console.log(req.body); + + Tutorial.updateById( + req.params.id, + new Tutorial(req.body), + (err, data) => { + if (err) { + if (err.kind === "not_found") { + res.status(404).send({ + message: `Not found Tutorial with id ${req.params.id}.` + }); + } else { + res.status(500).send({ + message: "Error updating Tutorial with id " + req.params.id + }); + } + } else res.send(data); + } + ); +}; + +// Delete a Tutorial with the specified id in the request +exports.delete = (req, res) => { + Tutorial.remove(req.params.id, (err, data) => { + if (err) { + if (err.kind === "not_found") { + res.status(404).send({ + message: `Not found Tutorial with id ${req.params.id}.` + }); + } else { + res.status(500).send({ + message: "Could not delete Tutorial with id " + req.params.id + }); + } + } else res.send({ message: `Tutorial was deleted successfully!` }); + }); +}; + +// Delete all Tutorials from the database. +exports.deleteAll = (req, res) => { + Tutorial.removeAll((err, data) => { + if (err) + res.status(500).send({ + message: + err.message || "Some error occurred while removing all tutorials." + }); + else res.send({ message: `All Tutorials were deleted successfully!` }); + }); +}; diff --git a/app/models/customer.model.js b/app/models/customer.model.js deleted file mode 100644 index 2aa3bf3..0000000 --- a/app/models/customer.model.js +++ /dev/null @@ -1,110 +0,0 @@ -const sql = require("./db.js"); - -// constructor -const Customer = function(customer) { - this.email = customer.email; - this.name = customer.name; - this.active = customer.active; -}; - -Customer.create = (newCustomer, result) => { - sql.query("INSERT INTO customers SET ?", newCustomer, (err, res) => { - if (err) { - console.log("error: ", err); - result(err, null); - return; - } - - console.log("created customer: ", { id: res.insertId, ...newCustomer }); - result(null, { id: res.insertId, ...newCustomer }); - }); -}; - -Customer.findById = (customerId, result) => { - sql.query(`SELECT * FROM customers WHERE id = ${customerId}`, (err, res) => { - if (err) { - console.log("error: ", err); - result(err, null); - return; - } - - if (res.length) { - console.log("found customer: ", res[0]); - result(null, res[0]); - return; - } - - // not found Customer with the id - result({ kind: "not_found" }, null); - }); -}; - -Customer.getAll = result => { - sql.query("SELECT * FROM customers", (err, res) => { - if (err) { - console.log("error: ", err); - result(null, err); - return; - } - - console.log("customers: ", res); - result(null, res); - }); -}; - -Customer.updateById = (id, customer, result) => { - sql.query( - "UPDATE customers SET email = ?, name = ?, active = ? WHERE id = ?", - [customer.email, customer.name, customer.active, id], - (err, res) => { - if (err) { - console.log("error: ", err); - result(null, err); - return; - } - - if (res.affectedRows == 0) { - // not found Customer with the id - result({ kind: "not_found" }, null); - return; - } - - console.log("updated customer: ", { id: id, ...customer }); - result(null, { id: id, ...customer }); - } - ); -}; - -Customer.remove = (id, result) => { - sql.query("DELETE FROM customers WHERE id = ?", id, (err, res) => { - if (err) { - console.log("error: ", err); - result(null, err); - return; - } - - if (res.affectedRows == 0) { - // not found Customer with the id - result({ kind: "not_found" }, null); - return; - } - - console.log("deleted customer with id: ", id); - result(null, res); - }); -}; - -Customer.removeAll = result => { - sql.query("DELETE FROM customers", (err, res) => { - if (err) { - console.log("error: ", err); - result(null, err); - return; - } - - console.log(`deleted ${res.affectedRows} customers`); - result(null, res); - }); -}; - -module.exports = Customer; diff --git a/app/models/tutorial.model.js b/app/models/tutorial.model.js new file mode 100644 index 0000000..17dc453 --- /dev/null +++ b/app/models/tutorial.model.js @@ -0,0 +1,129 @@ +const sql = require("./db.js"); + +// constructor +const Tutorial = function(tutorial) { + this.title = tutorial.title; + this.description = tutorial.description; + this.published = tutorial.published; +}; + +Tutorial.create = (newTutorial, result) => { + sql.query("INSERT INTO tutorials SET ?", newTutorial, (err, res) => { + if (err) { + console.log("error: ", err); + result(err, null); + return; + } + + console.log("created tutorial: ", { id: res.insertId, ...newTutorial }); + result(null, { id: res.insertId, ...newTutorial }); + }); +}; + +Tutorial.findById = (id, result) => { + sql.query(`SELECT * FROM tutorials WHERE id = ${id}`, (err, res) => { + if (err) { + console.log("error: ", err); + result(err, null); + return; + } + + if (res.length) { + console.log("found tutorial: ", res[0]); + result(null, res[0]); + return; + } + + // not found Tutorial with the id + result({ kind: "not_found" }, null); + }); +}; + +Tutorial.getAll = (title, result) => { + let query = "SELECT * FROM tutorials"; + + if (title) { + query += ` WHERE title LIKE '%${title}%'`; + } + + sql.query(query, (err, res) => { + if (err) { + console.log("error: ", err); + result(null, err); + return; + } + + console.log("tutorials: ", res); + result(null, res); + }); +}; + +Tutorial.getAllPublished = result => { + sql.query("SELECT * FROM tutorials WHERE published=true", (err, res) => { + if (err) { + console.log("error: ", err); + result(null, err); + return; + } + + console.log("tutorials: ", res); + result(null, res); + }); +}; + +Tutorial.updateById = (id, tutorial, result) => { + sql.query( + "UPDATE tutorials SET title = ?, description = ?, published = ? WHERE id = ?", + [tutorial.title, tutorial.description, tutorial.published, id], + (err, res) => { + if (err) { + console.log("error: ", err); + result(null, err); + return; + } + + if (res.affectedRows == 0) { + // not found Tutorial with the id + result({ kind: "not_found" }, null); + return; + } + + console.log("updated tutorial: ", { id: id, ...tutorial }); + result(null, { id: id, ...tutorial }); + } + ); +}; + +Tutorial.remove = (id, result) => { + sql.query("DELETE FROM tutorials WHERE id = ?", id, (err, res) => { + if (err) { + console.log("error: ", err); + result(null, err); + return; + } + + if (res.affectedRows == 0) { + // not found Tutorial with the id + result({ kind: "not_found" }, null); + return; + } + + console.log("deleted tutorial with id: ", id); + result(null, res); + }); +}; + +Tutorial.removeAll = result => { + sql.query("DELETE FROM tutorials", (err, res) => { + if (err) { + console.log("error: ", err); + result(null, err); + return; + } + + console.log(`deleted ${res.affectedRows} tutorials`); + result(null, res); + }); +}; + +module.exports = Tutorial; diff --git a/app/routes/customer.routes.js b/app/routes/customer.routes.js deleted file mode 100644 index 2137e50..0000000 --- a/app/routes/customer.routes.js +++ /dev/null @@ -1,21 +0,0 @@ -module.exports = app => { - const customers = require("../controllers/customer.controller.js"); - - // Create a new Customer - app.post("/customers", customers.create); - - // Retrieve all Customers - app.get("/customers", customers.findAll); - - // Retrieve a single Customer with customerId - app.get("/customers/:customerId", customers.findOne); - - // Update a Customer with customerId - app.put("/customers/:customerId", customers.update); - - // Delete a Customer with customerId - app.delete("/customers/:customerId", customers.delete); - - // Create a new Customer - app.delete("/customers", customers.deleteAll); -}; diff --git a/app/routes/tutorial.routes.js b/app/routes/tutorial.routes.js new file mode 100644 index 0000000..8dbbb78 --- /dev/null +++ b/app/routes/tutorial.routes.js @@ -0,0 +1,28 @@ +module.exports = app => { + const tutorials = require("../controllers/tutorial.controller.js"); + + var router = require("express").Router(); + + // Create a new Tutorial + router.post("/", tutorials.create); + + // Retrieve all Tutorials + router.get("/", tutorials.findAll); + + // Retrieve all published Tutorials + router.get("/published", tutorials.findAllPublished); + + // Retrieve a single Tutorial with id + router.get("/:id", tutorials.findOne); + + // Update a Tutorial with id + router.put("/:id", tutorials.update); + + // Delete a Tutorial with id + router.delete("/:id", tutorials.delete); + + // Delete all Tutorials + router.delete("/", tutorials.deleteAll); + + app.use('/api/tutorials', router); +}; diff --git a/package.json b/package.json index 4cfc689..ef1deac 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "author": "bezkoder", "license": "ISC", "dependencies": { - "body-parser": "^1.19.0", + "cors": "^2.8.5", "express": "^4.17.1", "mysql": "^2.17.1" } diff --git a/server.js b/server.js index 45bf996..d81441e 100644 --- a/server.js +++ b/server.js @@ -1,23 +1,30 @@ const express = require("express"); -const bodyParser = require("body-parser"); +// const bodyParser = require("body-parser"); /* deprecated */ +const cors = require("cors"); const app = express(); +var corsOptions = { + origin: "http://localhost:8081" +}; + +app.use(cors(corsOptions)); + // parse requests of content-type - application/json -app.use(bodyParser.json()); +app.use(express.json()); /* bodyParser.json() is deprecated */ // parse requests of content-type - application/x-www-form-urlencoded -app.use(bodyParser.urlencoded({ extended: true })); +app.use(express.urlencoded({ extended: true })); /* bodyParser.urlencoded() is deprecated */ // simple route app.get("/", (req, res) => { res.json({ message: "Welcome to bezkoder application." }); }); -require("./app/routes/customer.routes.js")(app); +require("./app/routes/tutorial.routes.js")(app); // set port, listen for requests -const PORT = process.env.PORT || 3000; +const PORT = process.env.PORT || 8080; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}.`); });