├── .gitignore ├── .DS_Store ├── public ├── allUsers.png ├── getUser.png ├── deleteUser.png ├── insertUser.png └── updateUser.png ├── model └── services.js ├── api-routes.js ├── package.json ├── index.js ├── controller └── controller.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/REST-API-Express-Node-MongoDB/master/.DS_Store -------------------------------------------------------------------------------- /public/allUsers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/REST-API-Express-Node-MongoDB/master/public/allUsers.png -------------------------------------------------------------------------------- /public/getUser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/REST-API-Express-Node-MongoDB/master/public/getUser.png -------------------------------------------------------------------------------- /public/deleteUser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/REST-API-Express-Node-MongoDB/master/public/deleteUser.png -------------------------------------------------------------------------------- /public/insertUser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/REST-API-Express-Node-MongoDB/master/public/insertUser.png -------------------------------------------------------------------------------- /public/updateUser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/REST-API-Express-Node-MongoDB/master/public/updateUser.png -------------------------------------------------------------------------------- /model/services.js: -------------------------------------------------------------------------------- 1 | 2 | var mongoose = require('mongoose'); 3 | // Setup the schema 4 | var userSchema = mongoose.Schema({ 5 | name: { 6 | type: String, 7 | required: true 8 | }, 9 | email: { 10 | type: String, 11 | required: true 12 | }, 13 | create_date: { 14 | type: Date, 15 | default: Date.now 16 | } 17 | }); 18 | // Export User model 19 | var User = module.exports = mongoose.model('user', userSchema); 20 | module.exports.get = function (callback, limit) { 21 | User.find(callback).limit(limit); 22 | } -------------------------------------------------------------------------------- /api-routes.js: -------------------------------------------------------------------------------- 1 | var router = require('express').Router(); 2 | var controller = require('./controller/controller.js'); 3 | router.get('/', function(req, res){ 4 | res.json({ 5 | status: 'API is Working', 6 | message: 'Node + Express + MongoDB: Nodemon Server', 7 | }); 8 | }); 9 | // users routes 10 | router.route('/users').get(controller.index) 11 | .post(controller.newUser); 12 | 13 | router.route('/user/:id').get(controller.view) 14 | .put(controller.update) 15 | .delete(controller.delete); 16 | // Expose API routes to public 17 | module.exports = router; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rest-api-express-node", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/cmuth001/rest-api-express-node.git" 12 | }, 13 | "author": "", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/cmuth001/rest-api-express-node/issues" 17 | }, 18 | "homepage": "https://github.com/cmuth001/rest-api-express-node#readme", 19 | "dependencies": { 20 | "body-parser": "^1.19.0", 21 | "express": "^4.17.1", 22 | "mongodb": "^2.2.33", 23 | "mongoose": "^5.6.5" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // Importing Express Framework 2 | var express = require("express"); 3 | 4 | var bodyParser = require('body-parser'); 5 | // Import Mongoose 6 | let mongoose = require('mongoose'); 7 | // Intializing the app 8 | var app = express(); 9 | 10 | // Import Route Module 11 | var apiRoutes = require('./api-routes'); 12 | // Configure bodyparser to handle post requests 13 | app.use(bodyParser.urlencoded({ 14 | extended: true 15 | })); 16 | app.use(bodyParser.json()); 17 | // Setup server port 18 | var port = process.env.PORT || 3000; 19 | app.use('/api', apiRoutes); 20 | // Connect to Mongoose and set connection variable 21 | mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true}); 22 | var db = mongoose.connection; 23 | 24 | // Added check for DB connection 25 | if(!db) 26 | console.log("Error connecting db") 27 | else 28 | console.log("Db connected successfully") 29 | // Sending message to the default Route 30 | app.get('/', function (req, res) { 31 | res.json({ 32 | status: 'Main page', 33 | message: 'Welcome to the world of RESTAPI', 34 | description: 'Goto /api to explore API' 35 | }); 36 | }); 37 | // Launch app to listen to the specified PORT 38 | app.listen(3000, () => { 39 | console.log(`Server running on port ${port}`); 40 | }); 41 | 42 | -------------------------------------------------------------------------------- /controller/controller.js: -------------------------------------------------------------------------------- 1 | var User = require('../model/services.js'); 2 | 3 | exports.index = (req, res) => { 4 | User.get((err, users) => { 5 | if(err){ 6 | res.json({ 7 | status: "Error occured in getting users", 8 | message: err, 9 | }); 10 | } 11 | res.json({ 12 | status: "success!", 13 | message: "users retrieved successfully", 14 | data: users 15 | }); 16 | }); 17 | }; 18 | 19 | exports.newUser = (req, res) => { 20 | var user = new User(); 21 | console.log(req.body); 22 | user.name = req.body.name ? req.body.name : user.name; 23 | user.email = req.body.email ? req.body.email : user.email; 24 | 25 | user.save((err) => { 26 | if(err){ 27 | return res.json({ 28 | status: 'Error in inserting', 29 | message: err, 30 | }); 31 | } 32 | res.json({ 33 | status: 'New User inserted successfully!', 34 | message: user, 35 | }); 36 | }); 37 | }; 38 | 39 | exports.view = (req, res) => { 40 | // console.log(req.params.id); 41 | var id = req.params.id; 42 | 43 | User.findById(id, (err, user)=>{ 44 | if(err){ 45 | return res.json({ 46 | status: "Error In fetching user", 47 | message: err, 48 | }); 49 | } 50 | res.json({ 51 | status: 'User Found in the DB!', 52 | message: user 53 | }); 54 | }); 55 | }; 56 | 57 | exports.update = (req, res) => { 58 | var id = req.params.id; 59 | User.findById(id, (err, user) => { 60 | 61 | if(err){ 62 | return res.json({ 63 | status: 'Error in finding user id', 64 | message: err, 65 | }); 66 | } 67 | user.name = req.body.name?req.body.name:user.name; 68 | user.email = req.body.email?req.body.email: user.email 69 | user.save((err)=>{ 70 | if(err){ 71 | return res.json({ 72 | status: 'Error in updating user details', 73 | message: userrer, 74 | }); 75 | } 76 | res.json({ 77 | status: 'User details successfully updated', 78 | message: user, 79 | }); 80 | }); 81 | 82 | }); 83 | }; 84 | 85 | exports.delete = (req, res) => { 86 | var id = req.params.id; 87 | User.findById(id, (err, user)=>{ 88 | if(err){ 89 | return res.json({ 90 | status: 'Error in finding user to delete', 91 | message: err, 92 | }); 93 | } 94 | user.delete((err)=>{ 95 | if(err){ 96 | return res.json({ 97 | status: 'Error in deleting user', 98 | message: err, 99 | }); 100 | } 101 | res.json({ 102 | status: 'Successfully deleted', 103 | message: user 104 | }); 105 | }); 106 | }); 107 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A Simple REST API tutorial 2 | 3 | A simple REST API application implementation with NodeJs, Express and MongoDb(Mongoose) 4 | 5 | Implemented a simple API requests and Model to save/retrieve data from the database. 6 | 7 | Implement the following endpoints: 8 | - GET /api/users list all user 9 | - POST /api/users create new user 10 | - GET /api/user/{id} retrieve a single user 11 | - PUT /api/user/{id} update a single user 12 | - DELETE /api/user/{id} delete a single user 13 | 14 | ## Design 15 | We need to make sure that the base URL of our API endpoint is simple. Here we are designing API for User. 16 | 17 | - /users 18 | - /user/{id} 19 | 20 | 1. Most of the developers make mistake by using verb instead of using noun. Generally developers forgot that we have HTTP (GET, POST, PUT, DELETE) method to describe the endpoint and endup using a verb instead of noun. 21 | 22 | Example: API to get all the users 23 | 24 | **verb form:** /getAllUsers 25 | 26 | **noun form:** /users 27 | 28 | 2. Sometime API endpoint should give more information than just by **/?id='123'**. Design endpoint for query parameters 29 | - /user?name="chandu", should not use /user?getUserByName="chandu" 30 | - /user?id=123, should not use /user?getUserById=123 31 | - /user/?type="abc", should not use /user?getUserByType="abc" 32 | 33 | Avoid using verb forms in API endpints, and it will be more apt to use for function name in the backend. 34 | 35 | 3. Return endpoint as a Json format with status, code, ErrorMessage, body. 36 | ```json 37 | { 38 | status: "successfully retrieved", 39 | code: 200, 40 | data: [{},{},{}] 41 | } 42 | ``` 43 | 44 | ```json 45 | { 46 | status: "Failed in retrieving", 47 | code: 404, 48 | error: "error message" 49 | } 50 | ``` 51 | 4. If you are developing a production endpoint, it is always good to maintain ***versioning***. 52 | 53 | Like: 54 | 55 | - /v1/users 56 | - /v1/user/{id} 57 | 58 | - /v2/users 59 | - /v2/user/{id} 60 | 61 | Clients think that this is a stable version endpoints. 62 | 63 | Do not use versioning style like below 64 | 65 | - /v1.1/users 66 | - /v1.2/users 67 | 68 | This shows the endpoint with (dot) versions are unstable versions and it is not clearly visible in the URLs. So always keep it as simple as possible. 69 | 70 | 71 | 72 | ## Usage 73 | 1. run npm install in your root project folder. 74 | 2. nodemon index.js 75 | 76 | 77 | ## Outputs 78 | 1. **GET /api/users**: List all user 79 | 80 | | ![All users](./public/allUsers.png) | 81 | |:---:| 82 | 83 | 2. **POST /api/users**: Create new user 84 | 85 | | ![Insert users](./public/insertUser.png) | 86 | |:---:| 87 | 88 | 3. **GET /api/user/{id}**: Retrieve a single user 89 | 90 | | ![Get user](./public/getUser.png) | 91 | |:---:| 92 | 93 | 4. **PUT /api/user/{id}**: Update single user 94 | 95 | | ![Update user](./public/updateUser.png) | 96 | |:---:| 97 | 98 | 5. **DELETE /api/user/{id}**: Delete single user 99 | 100 | | ![Delete user](./public/deleteUser.png) | 101 | |:---:| 102 | 103 | 104 | I hope this tutorial helped you in creating a simple **REST API using NodeJs and Mongodb**. To Know more about how to create secure REST API click [here](https://github.com/cmuth001/Secure-REST-API-Express-Node-MongoDB). 105 | --------------------------------------------------------------------------------