├── .gitignore ├── README.md ├── app ├── config │ └── db.config.js ├── controllers │ └── tutorial.controller.js ├── models │ ├── index.js │ └── tutorial.model.js └── routes │ └── turorial.routes.js ├── package.json └── server.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node.js Express & MongoDB: CRUD Rest APIs 2 | 3 | For more detail, please visit: 4 | > [Node.js, Express & MongoDb: Build a CRUD Rest Api example](https://www.bezkoder.com/node-express-mongodb-crud-rest-api/) 5 | 6 | Front-end that works well with this Back-end 7 | > [Axios Client](https://www.bezkoder.com/axios-request/) 8 | 9 | > [Angular 8](https://www.bezkoder.com/angular-crud-app/) / [Angular 10](https://www.bezkoder.com/angular-10-crud-app/) / [Angular 11](https://www.bezkoder.com/angular-11-crud-app/) / [Angular 12](https://www.bezkoder.com/angular-12-crud-app/) / [Angular 13](https://www.bezkoder.com/angular-13-crud-example/) / [Angular 14](https://www.bezkoder.com/angular-14-crud-example/) / [Angular 15](https://www.bezkoder.com/angular-15-crud-example/) / [Angular 16](https://www.bezkoder.com/angular-16-crud-example/) / [Angular 17](https://www.bezkoder.com/angular-17-crud-example/) 10 | 11 | > [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/) 12 | 13 | > [React Client](https://www.bezkoder.com/react-crud-web-api/) / [React Redux Client](https://www.bezkoder.com/react-redux-crud-example/) 14 | 15 | ## More Practice 16 | > [Server side Pagination in Node.js with MongoDB and Mongoose](https://www.bezkoder.com/node-js-mongodb-pagination/) 17 | 18 | > [Node.js Express File Upload to MongoDB example](https://www.bezkoder.com/node-js-upload-store-images-mongodb/) 19 | 20 | Security: 21 | > [Node.js + MongoDB: User Authentication & Authorization with JWT](https://www.bezkoder.com/node-js-mongodb-auth-jwt/) 22 | 23 | Associations: 24 | > [MongoDB One-to-One relationship tutorial with Mongoose examples](https://www.bezkoder.com/mongoose-one-to-one-relationship-example/) 25 | 26 | > [MongoDB One-to-Many Relationship tutorial with Mongoose examples](https://www.bezkoder.com/mongoose-one-to-many-relationship/) 27 | 28 | > [MongoDB Many-to-Many Relationship with Mongoose examples](https://www.bezkoder.com/mongodb-many-to-many-mongoose/) 29 | 30 | Fullstack: 31 | > [Vue + Node.js + Express + MongoDB example](https://www.bezkoder.com/vue-node-express-mongodb-mevn-crud/) 32 | 33 | > [Angular 8 + Node.js + Express + MongoDB example](https://www.bezkoder.com/angular-mongodb-node-express/) 34 | 35 | > [Angular 10 + Node.js + Express + MongoDB example](https://www.bezkoder.com/angular-10-mongodb-node-express/) 36 | 37 | > [Angular 11 + Node.js + Express + MongoDB example](https://www.bezkoder.com/angular-11-mongodb-node-js-express/) 38 | 39 | > [Angular 12 + Node.js + Express + MongoDB example](https://www.bezkoder.com/angular-12-mongodb-node-js-express/) 40 | 41 | > [Angular 13 + Node.js + Express + MongoDB example](https://www.bezkoder.com/mean-stack-crud-example-angular-13/) 42 | 43 | > [Angular 14 + Node.js + Express + MongoDB example](https://www.bezkoder.com/mean-stack-crud-example-angular-14/) 44 | 45 | > [Angular 15 + Node.js + Express + MongoDB example](https://www.bezkoder.com/angular-15-node-js-express-mongodb/) 46 | 47 | > [Angular 16 + Node.js + Express + MongoDB example](https://www.bezkoder.com/angular-16-node-js-express-mongodb/) 48 | 49 | > [Angular 17 + Node.js + Express + MongoDB example](https://www.bezkoder.com/angular-17-node-js-express-mongodb/) 50 | 51 | > [React + Node.js + Express + MongoDB example](https://www.bezkoder.com/react-node-express-mongodb-mern-stack/) 52 | 53 | Integration (run back-end & front-end on same server/port) 54 | > [Integrate React with Node.js Restful Services](https://www.bezkoder.com/integrate-react-express-same-server-port/) 55 | 56 | > [Integrate Angular with Node.js Restful Services](https://www.bezkoder.com/integrate-angular-12-node-js/) 57 | 58 | > [Integrate Vue with Node.js Restful Services](https://www.bezkoder.com/serve-vue-app-express/) 59 | 60 | ## Project setup 61 | ``` 62 | npm install 63 | ``` 64 | 65 | ### Run 66 | ``` 67 | node server.js 68 | ``` 69 | -------------------------------------------------------------------------------- /app/config/db.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: "mongodb://0.0.0.0:27017/bezkoder_db" 3 | }; 4 | -------------------------------------------------------------------------------- /app/controllers/tutorial.controller.js: -------------------------------------------------------------------------------- 1 | const db = require("../models"); 2 | const Tutorial = db.tutorials; 3 | 4 | // Create and Save a new Tutorial 5 | exports.create = (req, res) => { 6 | // Validate request 7 | if (!req.body.title) { 8 | res.status(400).send({ message: "Content can not be empty!" }); 9 | return; 10 | } 11 | 12 | // Create a Tutorial 13 | const tutorial = new Tutorial({ 14 | title: req.body.title, 15 | description: req.body.description, 16 | published: req.body.published ? req.body.published : false 17 | }); 18 | 19 | // Save Tutorial in the database 20 | tutorial 21 | .save(tutorial) 22 | .then(data => { 23 | res.send(data); 24 | }) 25 | .catch(err => { 26 | res.status(500).send({ 27 | message: 28 | err.message || "Some error occurred while creating the Tutorial." 29 | }); 30 | }); 31 | }; 32 | 33 | // Retrieve all Tutorials from the database. 34 | exports.findAll = (req, res) => { 35 | const title = req.query.title; 36 | var condition = title ? { title: { $regex: new RegExp(title), $options: "i" } } : {}; 37 | 38 | Tutorial.find(condition) 39 | .then(data => { 40 | res.send(data); 41 | }) 42 | .catch(err => { 43 | res.status(500).send({ 44 | message: 45 | err.message || "Some error occurred while retrieving tutorials." 46 | }); 47 | }); 48 | }; 49 | 50 | // Find a single Tutorial with an id 51 | exports.findOne = (req, res) => { 52 | const id = req.params.id; 53 | 54 | Tutorial.findById(id) 55 | .then(data => { 56 | if (!data) 57 | res.status(404).send({ message: "Not found Tutorial with id " + id }); 58 | else res.send(data); 59 | }) 60 | .catch(err => { 61 | res 62 | .status(500) 63 | .send({ message: "Error retrieving Tutorial with id=" + id }); 64 | }); 65 | }; 66 | 67 | // Update a Tutorial by the id in the request 68 | exports.update = (req, res) => { 69 | if (!req.body) { 70 | return res.status(400).send({ 71 | message: "Data to update can not be empty!" 72 | }); 73 | } 74 | 75 | const id = req.params.id; 76 | 77 | Tutorial.findByIdAndUpdate(id, req.body, { useFindAndModify: false }) 78 | .then(data => { 79 | if (!data) { 80 | res.status(404).send({ 81 | message: `Cannot update Tutorial with id=${id}. Maybe Tutorial was not found!` 82 | }); 83 | } else res.send({ message: "Tutorial was updated successfully." }); 84 | }) 85 | .catch(err => { 86 | res.status(500).send({ 87 | message: "Error updating Tutorial with id=" + id 88 | }); 89 | }); 90 | }; 91 | 92 | // Delete a Tutorial with the specified id in the request 93 | exports.delete = (req, res) => { 94 | const id = req.params.id; 95 | 96 | Tutorial.findByIdAndRemove(id, { useFindAndModify: false }) 97 | .then(data => { 98 | if (!data) { 99 | res.status(404).send({ 100 | message: `Cannot delete Tutorial with id=${id}. Maybe Tutorial was not found!` 101 | }); 102 | } else { 103 | res.send({ 104 | message: "Tutorial was deleted successfully!" 105 | }); 106 | } 107 | }) 108 | .catch(err => { 109 | res.status(500).send({ 110 | message: "Could not delete Tutorial with id=" + id 111 | }); 112 | }); 113 | }; 114 | 115 | // Delete all Tutorials from the database. 116 | exports.deleteAll = (req, res) => { 117 | Tutorial.deleteMany({}) 118 | .then(data => { 119 | res.send({ 120 | message: `${data.deletedCount} Tutorials were deleted successfully!` 121 | }); 122 | }) 123 | .catch(err => { 124 | res.status(500).send({ 125 | message: 126 | err.message || "Some error occurred while removing all tutorials." 127 | }); 128 | }); 129 | }; 130 | 131 | // Find all published Tutorials 132 | exports.findAllPublished = (req, res) => { 133 | Tutorial.find({ published: true }) 134 | .then(data => { 135 | res.send(data); 136 | }) 137 | .catch(err => { 138 | res.status(500).send({ 139 | message: 140 | err.message || "Some error occurred while retrieving tutorials." 141 | }); 142 | }); 143 | }; 144 | -------------------------------------------------------------------------------- /app/models/index.js: -------------------------------------------------------------------------------- 1 | const dbConfig = require("../config/db.config.js"); 2 | 3 | const mongoose = require("mongoose"); 4 | mongoose.Promise = global.Promise; 5 | 6 | const db = {}; 7 | db.mongoose = mongoose; 8 | db.url = dbConfig.url; 9 | db.tutorials = require("./tutorial.model.js")(mongoose); 10 | 11 | module.exports = db; 12 | -------------------------------------------------------------------------------- /app/models/tutorial.model.js: -------------------------------------------------------------------------------- 1 | module.exports = mongoose => { 2 | var schema = mongoose.Schema( 3 | { 4 | title: String, 5 | description: String, 6 | published: Boolean 7 | }, 8 | { timestamps: true } 9 | ); 10 | 11 | schema.method("toJSON", function() { 12 | const { __v, _id, ...object } = this.toObject(); 13 | object.id = _id; 14 | return object; 15 | }); 16 | 17 | const Tutorial = mongoose.model("tutorial", schema); 18 | return Tutorial; 19 | }; 20 | -------------------------------------------------------------------------------- /app/routes/turorial.routes.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | const tutorials = require("../controllers/tutorial.controller.js"); 3 | 4 | var router = require("express").Router(); 5 | 6 | // Create a new Tutorial 7 | router.post("/", tutorials.create); 8 | 9 | // Retrieve all Tutorials 10 | router.get("/", tutorials.findAll); 11 | 12 | // Retrieve all published Tutorials 13 | router.get("/published", tutorials.findAllPublished); 14 | 15 | // Retrieve a single Tutorial with id 16 | router.get("/:id", tutorials.findOne); 17 | 18 | // Update a Tutorial with id 19 | router.put("/:id", tutorials.update); 20 | 21 | // Delete a Tutorial with id 22 | router.delete("/:id", tutorials.delete); 23 | 24 | // Create a new Tutorial 25 | router.delete("/", tutorials.deleteAll); 26 | 27 | app.use("/api/tutorials", router); 28 | }; 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-express-mongodb", 3 | "version": "1.0.0", 4 | "description": "Node.js Restful CRUD API with Node.js, Express and MongoDB", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "nodejs", 11 | "express", 12 | "rest", 13 | "api", 14 | "mongodb" 15 | ], 16 | "author": "bezkoder", 17 | "license": "ISC", 18 | "dependencies": { 19 | "cors": "^2.8.5", 20 | "express": "^4.18.2", 21 | "mongoose": "^6.11.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const cors = require("cors"); 3 | 4 | const app = express(); 5 | 6 | var corsOptions = { 7 | origin: "http://localhost:8081" 8 | }; 9 | 10 | app.use(cors(corsOptions)); 11 | 12 | // parse requests of content-type - application/json 13 | app.use(express.json()); 14 | 15 | // parse requests of content-type - application/x-www-form-urlencoded 16 | app.use(express.urlencoded({ extended: true })); 17 | 18 | const db = require("./app/models"); 19 | db.mongoose 20 | .connect(db.url, { 21 | useNewUrlParser: true, 22 | useUnifiedTopology: true 23 | }) 24 | .then(() => { 25 | console.log("Connected to the database!"); 26 | }) 27 | .catch(err => { 28 | console.log("Cannot connect to the database!", err); 29 | process.exit(); 30 | }); 31 | 32 | // simple route 33 | app.get("/", (req, res) => { 34 | res.json({ message: "Welcome to bezkoder application." }); 35 | }); 36 | 37 | require("./app/routes/turorial.routes")(app); 38 | 39 | // set port, listen for requests 40 | const PORT = process.env.PORT || 8080; 41 | app.listen(PORT, () => { 42 | console.log(`Server is running on port ${PORT}.`); 43 | }); 44 | --------------------------------------------------------------------------------