├── Dockerfile ├── README.md ├── dev.list ├── package-lock.json ├── src ├── app │ ├── controllers │ │ └── note.controller.js │ ├── models │ │ └── note.model.js │ └── routes │ │ └── note.routes.js ├── config │ └── database.config.js ├── package.json └── server.js └── start.sh /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10.13.0 2 | 3 | MAINTAINER Badri Nath Pathak(badri.pathak@mindtree.com) 4 | 5 | RUN apt-get update && apt-get install -y \ 6 | curl \ 7 | git \ 8 | vim 9 | 10 | WORKDIR /usr/src/app 11 | 12 | RUN mkdir -p /usr/src/app/CRUD-API-Node.js-Express-and-MongoDB 13 | 14 | COPY . CRUD-API-Node.js-Express-and-MongoDB/ 15 | 16 | 17 | WORKDIR /usr/src/app/CRUD-API-Node.js-Express-and-MongoDB 18 | 19 | RUN cd src && npm install 20 | 21 | 22 | COPY start.sh /start.sh 23 | RUN chmod +x /start.sh 24 | 25 | CMD ["/start.sh"] 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Building a Restful CRUD API with Node.js, Express and MongoDB # 2 | ## We’ll be building a RESTful CRUD (Create, Retrieve, Update, Delete) API with Node.js, Express and MongoDB. ## 3 | ### We’ll use Mongoose for interacting with the MongoDB instance. ### 4 | 5 | Express is one of the most popular web frameworks for node.js. It is built on top of node.js http module, and adds support for routing, middleware, view system etc. It is very simple and minimal, unlike other frameworks that try do way to much, thereby reducing the flexibility for developers to have their own design choices. 6 | 7 | Mongoose is an ODM (Object Document Mapping) tool for Node.js and MongoDB. It helps you convert the objects in your code to documents in the database and vice versa. 8 | 9 | ## Prerequisites: 10 | Please install MongoDB in your machine if you have not done already. Checkout the official MogngoDB installation manual for any help with the installation. 11 | 12 | 13 | ### Our Application ### 14 | In this tutorial, We will be building a simple Note-Taking application. We will build Rest APIs for creating, listing, editing and deleting a Note. 15 | 16 | We’ll start by building a simple web server and then move on to configuring the database, building the Note model and different routes for handling all the CRUD operations. 17 | 18 | Finally, we’ll test our REST APIs using Postman. 19 | 20 | We’ll heavily use ES6 features like let, const, arrow functions, promises etc. It’s good to familiarize yourself with these features. I recommend this re-introduction to Javascript to brush up these concepts. 21 | 22 | ### Creating the Application 23 | #### 1. Fire up your terminal and create a new folder for the application. 24 | 25 | $ mkdir node-easy-notes-app 26 | #### 2. Initialize the application with a package.json file 27 | 28 | Go to the root folder of your application and type npm init to initialize your app with a package.json file. 29 | 30 | $ cd node-easy-notes-app 31 | $ npm init 32 | 33 | #### 3. Install dependencies 34 | 35 | We will need express, mongoose and body-parser modules in our application. Let’s install them by typing the following command - 36 | 37 | $ npm install express body-parser mongoose --save 38 | 39 | ### Setting up the web server 40 | Let’s now create the main entry point of our application. Create a new file named server.js in the root folder of the application with the following contents - 41 | ``` 42 | const express = require('express'); 43 | const bodyParser = require('body-parser'); 44 | 45 | // create express app 46 | const app = express(); 47 | 48 | // parse requests of content-type - application/x-www-form-urlencoded 49 | app.use(bodyParser.urlencoded({ extended: true })) 50 | 51 | // parse requests of content-type - application/json 52 | app.use(bodyParser.json()) 53 | 54 | // define a simple route 55 | app.get('/', (req, res) => { 56 | res.json({"message": "Welcome to EasyNotes application. Take notes quickly. Organize and keep track of all your notes."}); 57 | }); 58 | 59 | // listen for requests 60 | app.listen(3000, () => { 61 | console.log("Server is listening on port 3000"); 62 | }); 63 | ``` 64 | First, We import express and body-parser modules. Express, as you know, is a web framework that we’ll be using for building the REST APIs, and body-parser is a module that parses the request (of various content types) and creates a req.body object that we can access in our routes. 65 | 66 | Then, We create an express app, and add two body-parser middlewares using express’s app.use() method. A middleware is a function that has access to the request and response objects. It can execute any code, transform the request object, or return a response. 67 | 68 | Then, We define a simple GET route which returns a welcome message to the clients. 69 | 70 | Finally, We listen on port 3000 for incoming connections. 71 | 72 | All right! Let’s now run the server and go to http://localhost:3000 to access the route we just defined. 73 | 74 | $ node server.js 75 | Server is listening on port 3000 76 | 77 | ### Configuring and Connecting to the database 78 | I like to keep all the configurations for the app in a separate folder. Let’s create a new folder config in the root folder of our application for keeping all the configurations - 79 | 80 | $ mkdir config 81 | $ cd config 82 | Now, Create a new file database.config.js inside config folder with the following contents - 83 | ``` 84 | module.exports = { 85 | url: 'mongodb://localhost:27017/easy-notes' 86 | } 87 | ``` 88 | We’ll now import the above database configuration in server.js and connect to the database using mongoose. 89 | 90 | Add the following code to the server.js file after app.use(bodyParser.json()) line - 91 | 92 | #### Configuring the database 93 | ``` 94 | const dbConfig = require('./config/database.config.js'); 95 | const mongoose = require('mongoose'); 96 | 97 | mongoose.Promise = global.Promise; 98 | 99 | // Connecting to the database 100 | mongoose.connect(dbConfig.url, { 101 | useNewUrlParser: true 102 | }).then(() => { 103 | console.log("Successfully connected to the database"); 104 | }).catch(err => { 105 | console.log('Could not connect to the database. Exiting now...', err); 106 | process.exit(); 107 | }); 108 | ``` 109 | Please run the server and make sure that you’re able to connect to the database - 110 | 111 | $ node server.js 112 | Server is listening on port 3000 113 | Successfully connected to the database 114 | 115 | #### Defining the Note model in Mongoose 116 | Next, We will define the Note model. Create a new folder called app inside the root folder of the application, then create another folder called models inside the app folder - 117 | 118 | $ mkdir -p app/models 119 | $ cd app/models 120 | Now, create a file called note.model.js inside app/models folder with the following contents - 121 | 122 | ``` 123 | const mongoose = require('mongoose'); 124 | 125 | const NoteSchema = mongoose.Schema({ 126 | title: String, 127 | content: String 128 | }, { 129 | timestamps: true 130 | }); 131 | 132 | module.exports = mongoose.model('Note', NoteSchema); 133 | ``` 134 | The Note model is very simple. It contains a title and a content field. I have also added a timestamps option to the schema. 135 | 136 | Mongoose uses this option to automatically add two new fields - createdAt and updatedAt to the schema. 137 | 138 | #### Defining Routes using Express 139 | Next up is the routes for the Notes APIs. Create a new folder called routes inside the app folder. 140 | 141 | $ mkdir app/routes 142 | $ cd app/routes 143 | Now, create a new file called note.routes.js inside app/routes folder with the following contents - 144 | ``` 145 | module.exports = (app) => { 146 | const notes = require('../controllers/note.controller.js'); 147 | 148 | // Create a new Note 149 | app.post('/notes', notes.create); 150 | 151 | // Retrieve all Notes 152 | app.get('/notes', notes.findAll); 153 | 154 | // Retrieve a single Note with noteId 155 | app.get('/notes/:noteId', notes.findOne); 156 | 157 | // Update a Note with noteId 158 | app.put('/notes/:noteId', notes.update); 159 | 160 | // Delete a Note with noteId 161 | app.delete('/notes/:noteId', notes.delete); 162 | } 163 | ``` 164 | Note that We have added a require statement for note.controller.js file. We’ll define the controller file in the next section. The controller will contain methods for handling all the CRUD operations. 165 | 166 | Before defining the controller, let’s first include the routes in server.js. Add the following require statement before app.listen() line inside server.js file. 167 | ``` 168 | // ........ 169 | 170 | // Require Notes routes 171 | require('./app/routes/note.routes.js')(app); 172 | 173 | // ........ 174 | ``` 175 | If you run the server now, you’ll get the following error - 176 | 177 | $ node server.js 178 | module.js:472 179 | throw err; 180 | ^ 181 | 182 | Error: Cannot find module '../controllers/note.controller.js' 183 | This is because we haven’t defined the controller yet. Let’s do that now. 184 | 185 | #### Writing the Controller functions 186 | Create a new folder called controllers inside the app folder, then create a new file called note.controller.js inside app/controllers folder with the following contents - 187 | ``` 188 | const Note = require('../models/note.model.js'); 189 | 190 | // Create and Save a new Note 191 | exports.create = (req, res) => { 192 | 193 | }; 194 | 195 | // Retrieve and return all notes from the database. 196 | exports.findAll = (req, res) => { 197 | 198 | }; 199 | 200 | // Find a single note with a noteId 201 | exports.findOne = (req, res) => { 202 | 203 | }; 204 | 205 | // Update a note identified by the noteId in the request 206 | exports.update = (req, res) => { 207 | 208 | }; 209 | 210 | // Delete a note with the specified noteId in the request 211 | exports.delete = (req, res) => { 212 | 213 | }; 214 | ``` 215 | 216 | #### Let’s now look at the implementation of the above controller functions one by one - 217 | 218 | ##### Creating a new Note 219 | ``` 220 | // Create and Save a new Note 221 | exports.create = (req, res) => { 222 | // Validate request 223 | if(!req.body.content) { 224 | return res.status(400).send({ 225 | message: "Note content can not be empty" 226 | }); 227 | } 228 | 229 | // Create a Note 230 | const note = new Note({ 231 | title: req.body.title || "Untitled Note", 232 | content: req.body.content 233 | }); 234 | 235 | // Save Note in the database 236 | note.save() 237 | .then(data => { 238 | res.send(data); 239 | }).catch(err => { 240 | res.status(500).send({ 241 | message: err.message || "Some error occurred while creating the Note." 242 | }); 243 | }); 244 | }; 245 | ``` 246 | ##### Retrieving all Notes 247 | ``` 248 | // Retrieve and return all notes from the database. 249 | exports.findAll = (req, res) => { 250 | Note.find() 251 | .then(notes => { 252 | res.send(notes); 253 | }).catch(err => { 254 | res.status(500).send({ 255 | message: err.message || "Some error occurred while retrieving notes." 256 | }); 257 | }); 258 | }; 259 | ``` 260 | ##### Retrieving a single Note 261 | ``` 262 | // Find a single note with a noteId 263 | exports.findOne = (req, res) => { 264 | Note.findById(req.params.noteId) 265 | .then(note => { 266 | if(!note) { 267 | return res.status(404).send({ 268 | message: "Note not found with id " + req.params.noteId 269 | }); 270 | } 271 | res.send(note); 272 | }).catch(err => { 273 | if(err.kind === 'ObjectId') { 274 | return res.status(404).send({ 275 | message: "Note not found with id " + req.params.noteId 276 | }); 277 | } 278 | return res.status(500).send({ 279 | message: "Error retrieving note with id " + req.params.noteId 280 | }); 281 | }); 282 | }; 283 | ``` 284 | ##### Updating a Note 285 | ``` 286 | // Update a note identified by the noteId in the request 287 | exports.update = (req, res) => { 288 | // Validate Request 289 | if(!req.body.content) { 290 | return res.status(400).send({ 291 | message: "Note content can not be empty" 292 | }); 293 | } 294 | 295 | // Find note and update it with the request body 296 | Note.findByIdAndUpdate(req.params.noteId, { 297 | title: req.body.title || "Untitled Note", 298 | content: req.body.content 299 | }, {new: true}) 300 | .then(note => { 301 | if(!note) { 302 | return res.status(404).send({ 303 | message: "Note not found with id " + req.params.noteId 304 | }); 305 | } 306 | res.send(note); 307 | }).catch(err => { 308 | if(err.kind === 'ObjectId') { 309 | return res.status(404).send({ 310 | message: "Note not found with id " + req.params.noteId 311 | }); 312 | } 313 | return res.status(500).send({ 314 | message: "Error updating note with id " + req.params.noteId 315 | }); 316 | }); 317 | }; 318 | ``` 319 | The {new: true} option in the findByIdAndUpdate() method is used to return the modified document to the then() function instead of the original. 320 | 321 | ##### Deleting a Note 322 | ``` 323 | // Delete a note with the specified noteId in the request 324 | exports.delete = (req, res) => { 325 | Note.findByIdAndRemove(req.params.noteId) 326 | .then(note => { 327 | if(!note) { 328 | return res.status(404).send({ 329 | message: "Note not found with id " + req.params.noteId 330 | }); 331 | } 332 | res.send({message: "Note deleted successfully!"}); 333 | }).catch(err => { 334 | if(err.kind === 'ObjectId' || err.name === 'NotFound') { 335 | return res.status(404).send({ 336 | message: "Note not found with id " + req.params.noteId 337 | }); 338 | } 339 | return res.status(500).send({ 340 | message: "Could not delete note with id " + req.params.noteId 341 | }); 342 | }); 343 | }; 344 | ``` 345 | 346 | #### 347 | Creating a new Note using POST /notes API 348 | Node Express Rest API Create a Note 349 | Retrieving all Notes using GET /notes API 350 | Node Express Rest API Retrieve All Notes 351 | Retrieving a single Note using GET /notes/:noteId API 352 | Node Express Rest API Retrieve a Single Note 353 | Updating a Note using PUT /notes/:noteId API 354 | Node Express Rest API Update a Note 355 | Deleting a Note using DELETE /notes/:noteId API 356 | Node Express Rest API Delete a Note 357 | ##### Conclusion 358 | We learned how to build rest apis in node.js using express framework and mongodb. 359 | -------------------------------------------------------------------------------- /dev.list: -------------------------------------------------------------------------------- 1 | mongo_host=10.0.0.8 2 | mongo_port=27017 3 | node_port=8080 4 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-express-crud", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.7", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 11 | "requires": { 12 | "mime-types": "~2.1.24", 13 | "negotiator": "0.6.2" 14 | } 15 | }, 16 | "array-flatten": { 17 | "version": "1.1.1", 18 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 19 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 20 | }, 21 | "bluebird": { 22 | "version": "3.5.1", 23 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", 24 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" 25 | }, 26 | "body-parser": { 27 | "version": "1.19.0", 28 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 29 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 30 | "requires": { 31 | "bytes": "3.1.0", 32 | "content-type": "~1.0.4", 33 | "debug": "2.6.9", 34 | "depd": "~1.1.2", 35 | "http-errors": "1.7.2", 36 | "iconv-lite": "0.4.24", 37 | "on-finished": "~2.3.0", 38 | "qs": "6.7.0", 39 | "raw-body": "2.4.0", 40 | "type-is": "~1.6.17" 41 | } 42 | }, 43 | "bson": { 44 | "version": "1.1.3", 45 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.3.tgz", 46 | "integrity": "sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg==" 47 | }, 48 | "bytes": { 49 | "version": "3.1.0", 50 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 51 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 52 | }, 53 | "content-disposition": { 54 | "version": "0.5.3", 55 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 56 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 57 | "requires": { 58 | "safe-buffer": "5.1.2" 59 | } 60 | }, 61 | "content-type": { 62 | "version": "1.0.4", 63 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 64 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 65 | }, 66 | "cookie": { 67 | "version": "0.4.0", 68 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 69 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 70 | }, 71 | "cookie-signature": { 72 | "version": "1.0.6", 73 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 74 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 75 | }, 76 | "debug": { 77 | "version": "2.6.9", 78 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 79 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 80 | "requires": { 81 | "ms": "2.0.0" 82 | } 83 | }, 84 | "depd": { 85 | "version": "1.1.2", 86 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 87 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 88 | }, 89 | "destroy": { 90 | "version": "1.0.4", 91 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 92 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 93 | }, 94 | "ee-first": { 95 | "version": "1.1.1", 96 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 97 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 98 | }, 99 | "encodeurl": { 100 | "version": "1.0.2", 101 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 102 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 103 | }, 104 | "escape-html": { 105 | "version": "1.0.3", 106 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 107 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 108 | }, 109 | "etag": { 110 | "version": "1.8.1", 111 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 112 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 113 | }, 114 | "express": { 115 | "version": "4.17.1", 116 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 117 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 118 | "requires": { 119 | "accepts": "~1.3.7", 120 | "array-flatten": "1.1.1", 121 | "body-parser": "1.19.0", 122 | "content-disposition": "0.5.3", 123 | "content-type": "~1.0.4", 124 | "cookie": "0.4.0", 125 | "cookie-signature": "1.0.6", 126 | "debug": "2.6.9", 127 | "depd": "~1.1.2", 128 | "encodeurl": "~1.0.2", 129 | "escape-html": "~1.0.3", 130 | "etag": "~1.8.1", 131 | "finalhandler": "~1.1.2", 132 | "fresh": "0.5.2", 133 | "merge-descriptors": "1.0.1", 134 | "methods": "~1.1.2", 135 | "on-finished": "~2.3.0", 136 | "parseurl": "~1.3.3", 137 | "path-to-regexp": "0.1.7", 138 | "proxy-addr": "~2.0.5", 139 | "qs": "6.7.0", 140 | "range-parser": "~1.2.1", 141 | "safe-buffer": "5.1.2", 142 | "send": "0.17.1", 143 | "serve-static": "1.14.1", 144 | "setprototypeof": "1.1.1", 145 | "statuses": "~1.5.0", 146 | "type-is": "~1.6.18", 147 | "utils-merge": "1.0.1", 148 | "vary": "~1.1.2" 149 | } 150 | }, 151 | "finalhandler": { 152 | "version": "1.1.2", 153 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 154 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 155 | "requires": { 156 | "debug": "2.6.9", 157 | "encodeurl": "~1.0.2", 158 | "escape-html": "~1.0.3", 159 | "on-finished": "~2.3.0", 160 | "parseurl": "~1.3.3", 161 | "statuses": "~1.5.0", 162 | "unpipe": "~1.0.0" 163 | } 164 | }, 165 | "forwarded": { 166 | "version": "0.1.2", 167 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 168 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 169 | }, 170 | "fresh": { 171 | "version": "0.5.2", 172 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 173 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 174 | }, 175 | "http-errors": { 176 | "version": "1.7.2", 177 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 178 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 179 | "requires": { 180 | "depd": "~1.1.2", 181 | "inherits": "2.0.3", 182 | "setprototypeof": "1.1.1", 183 | "statuses": ">= 1.5.0 < 2", 184 | "toidentifier": "1.0.0" 185 | } 186 | }, 187 | "iconv-lite": { 188 | "version": "0.4.24", 189 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 190 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 191 | "requires": { 192 | "safer-buffer": ">= 2.1.2 < 3" 193 | } 194 | }, 195 | "inherits": { 196 | "version": "2.0.3", 197 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 198 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 199 | }, 200 | "ipaddr.js": { 201 | "version": "1.9.0", 202 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", 203 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" 204 | }, 205 | "kareem": { 206 | "version": "2.3.1", 207 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz", 208 | "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw==" 209 | }, 210 | "media-typer": { 211 | "version": "0.3.0", 212 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 213 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 214 | }, 215 | "memory-pager": { 216 | "version": "1.5.0", 217 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 218 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", 219 | "optional": true 220 | }, 221 | "merge-descriptors": { 222 | "version": "1.0.1", 223 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 224 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 225 | }, 226 | "methods": { 227 | "version": "1.1.2", 228 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 229 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 230 | }, 231 | "mime": { 232 | "version": "1.6.0", 233 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 234 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 235 | }, 236 | "mime-db": { 237 | "version": "1.42.0", 238 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", 239 | "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" 240 | }, 241 | "mime-types": { 242 | "version": "2.1.25", 243 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", 244 | "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", 245 | "requires": { 246 | "mime-db": "1.42.0" 247 | } 248 | }, 249 | "mongodb": { 250 | "version": "3.3.4", 251 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.3.4.tgz", 252 | "integrity": "sha512-6fmHu3FJTpeZxacJcfjUGIP3BSteG0l2cxLkSrf1nnnS1OrlnVGiP9P/wAC4aB6dM6H4vQ2io8YDjkuPkje7AA==", 253 | "requires": { 254 | "bson": "^1.1.1", 255 | "require_optional": "^1.0.1", 256 | "safe-buffer": "^5.1.2", 257 | "saslprep": "^1.0.0" 258 | } 259 | }, 260 | "mongoose": { 261 | "version": "5.7.11", 262 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.7.11.tgz", 263 | "integrity": "sha512-KpXGBTXQTKfTlePpZMY+FBsk9wiyp2gzfph9AsLPfWleK1x2GJY+6xpKx2kKIgLustgNq16OOrqwlAOGUbv3kg==", 264 | "requires": { 265 | "bson": "~1.1.1", 266 | "kareem": "2.3.1", 267 | "mongodb": "3.3.4", 268 | "mongoose-legacy-pluralize": "1.0.2", 269 | "mpath": "0.6.0", 270 | "mquery": "3.2.2", 271 | "ms": "2.1.2", 272 | "regexp-clone": "1.0.0", 273 | "safe-buffer": "5.1.2", 274 | "sift": "7.0.1", 275 | "sliced": "1.0.1" 276 | }, 277 | "dependencies": { 278 | "ms": { 279 | "version": "2.1.2", 280 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 281 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 282 | } 283 | } 284 | }, 285 | "mongoose-legacy-pluralize": { 286 | "version": "1.0.2", 287 | "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", 288 | "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" 289 | }, 290 | "mpath": { 291 | "version": "0.6.0", 292 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.6.0.tgz", 293 | "integrity": "sha512-i75qh79MJ5Xo/sbhxrDrPSEG0H/mr1kcZXJ8dH6URU5jD/knFxCVqVC/gVSW7GIXL/9hHWlT9haLbCXWOll3qw==" 294 | }, 295 | "mquery": { 296 | "version": "3.2.2", 297 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz", 298 | "integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==", 299 | "requires": { 300 | "bluebird": "3.5.1", 301 | "debug": "3.1.0", 302 | "regexp-clone": "^1.0.0", 303 | "safe-buffer": "5.1.2", 304 | "sliced": "1.0.1" 305 | }, 306 | "dependencies": { 307 | "debug": { 308 | "version": "3.1.0", 309 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 310 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 311 | "requires": { 312 | "ms": "2.0.0" 313 | } 314 | } 315 | } 316 | }, 317 | "ms": { 318 | "version": "2.0.0", 319 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 320 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 321 | }, 322 | "negotiator": { 323 | "version": "0.6.2", 324 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 325 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 326 | }, 327 | "on-finished": { 328 | "version": "2.3.0", 329 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 330 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 331 | "requires": { 332 | "ee-first": "1.1.1" 333 | } 334 | }, 335 | "parseurl": { 336 | "version": "1.3.3", 337 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 338 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 339 | }, 340 | "path-to-regexp": { 341 | "version": "0.1.7", 342 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 343 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 344 | }, 345 | "proxy-addr": { 346 | "version": "2.0.5", 347 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", 348 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", 349 | "requires": { 350 | "forwarded": "~0.1.2", 351 | "ipaddr.js": "1.9.0" 352 | } 353 | }, 354 | "qs": { 355 | "version": "6.7.0", 356 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 357 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 358 | }, 359 | "range-parser": { 360 | "version": "1.2.1", 361 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 362 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 363 | }, 364 | "raw-body": { 365 | "version": "2.4.0", 366 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 367 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 368 | "requires": { 369 | "bytes": "3.1.0", 370 | "http-errors": "1.7.2", 371 | "iconv-lite": "0.4.24", 372 | "unpipe": "1.0.0" 373 | } 374 | }, 375 | "regexp-clone": { 376 | "version": "1.0.0", 377 | "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", 378 | "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" 379 | }, 380 | "require_optional": { 381 | "version": "1.0.1", 382 | "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", 383 | "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", 384 | "requires": { 385 | "resolve-from": "^2.0.0", 386 | "semver": "^5.1.0" 387 | } 388 | }, 389 | "resolve-from": { 390 | "version": "2.0.0", 391 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", 392 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" 393 | }, 394 | "safe-buffer": { 395 | "version": "5.1.2", 396 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 397 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 398 | }, 399 | "safer-buffer": { 400 | "version": "2.1.2", 401 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 402 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 403 | }, 404 | "saslprep": { 405 | "version": "1.0.3", 406 | "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", 407 | "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", 408 | "optional": true, 409 | "requires": { 410 | "sparse-bitfield": "^3.0.3" 411 | } 412 | }, 413 | "semver": { 414 | "version": "5.7.1", 415 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 416 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 417 | }, 418 | "send": { 419 | "version": "0.17.1", 420 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 421 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 422 | "requires": { 423 | "debug": "2.6.9", 424 | "depd": "~1.1.2", 425 | "destroy": "~1.0.4", 426 | "encodeurl": "~1.0.2", 427 | "escape-html": "~1.0.3", 428 | "etag": "~1.8.1", 429 | "fresh": "0.5.2", 430 | "http-errors": "~1.7.2", 431 | "mime": "1.6.0", 432 | "ms": "2.1.1", 433 | "on-finished": "~2.3.0", 434 | "range-parser": "~1.2.1", 435 | "statuses": "~1.5.0" 436 | }, 437 | "dependencies": { 438 | "ms": { 439 | "version": "2.1.1", 440 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 441 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 442 | } 443 | } 444 | }, 445 | "serve-static": { 446 | "version": "1.14.1", 447 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 448 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 449 | "requires": { 450 | "encodeurl": "~1.0.2", 451 | "escape-html": "~1.0.3", 452 | "parseurl": "~1.3.3", 453 | "send": "0.17.1" 454 | } 455 | }, 456 | "setprototypeof": { 457 | "version": "1.1.1", 458 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 459 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 460 | }, 461 | "sift": { 462 | "version": "7.0.1", 463 | "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", 464 | "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==" 465 | }, 466 | "sliced": { 467 | "version": "1.0.1", 468 | "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", 469 | "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" 470 | }, 471 | "sparse-bitfield": { 472 | "version": "3.0.3", 473 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 474 | "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", 475 | "optional": true, 476 | "requires": { 477 | "memory-pager": "^1.0.2" 478 | } 479 | }, 480 | "statuses": { 481 | "version": "1.5.0", 482 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 483 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 484 | }, 485 | "toidentifier": { 486 | "version": "1.0.0", 487 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 488 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 489 | }, 490 | "type-is": { 491 | "version": "1.6.18", 492 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 493 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 494 | "requires": { 495 | "media-typer": "0.3.0", 496 | "mime-types": "~2.1.24" 497 | } 498 | }, 499 | "unpipe": { 500 | "version": "1.0.0", 501 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 502 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 503 | }, 504 | "utils-merge": { 505 | "version": "1.0.1", 506 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 507 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 508 | }, 509 | "vary": { 510 | "version": "1.1.2", 511 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 512 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 513 | } 514 | } 515 | } 516 | -------------------------------------------------------------------------------- /src/app/controllers/note.controller.js: -------------------------------------------------------------------------------- 1 | const Note = require('../models/note.model.js'); 2 | 3 | 4 | // Create and Save a new Note 5 | exports.create = (req, res) => { 6 | // Validate request 7 | if(!req.body.content) { 8 | return res.status(400).send({ 9 | message: "Note content can not be empty" 10 | }); 11 | } 12 | 13 | // Create a Note 14 | const note = new Note({ 15 | title: req.body.title || "Untitled Note", 16 | content: req.body.content 17 | }); 18 | 19 | // Save Note in the database 20 | note.save() 21 | .then(data => { 22 | res.send(data); 23 | }).catch(err => { 24 | res.status(500).send({ 25 | message: err.message || "Some error occurred while creating the Note." 26 | }); 27 | }); 28 | }; 29 | 30 | // Retrieve and return all notes from the database. 31 | exports.findAll = (req, res) => { 32 | Note.find() 33 | .then(notes => { 34 | res.send(notes); 35 | }).catch(err => { 36 | res.status(500).send({ 37 | message: err.message || "Some error occurred while retrieving notes." 38 | }); 39 | }); 40 | }; 41 | 42 | // Find a single note with a noteId 43 | exports.findOne = (req, res) => { 44 | Note.findById(req.params.noteId) 45 | .then(note => { 46 | if(!note) { 47 | return res.status(404).send({ 48 | message: "Note not found with id " + req.params.noteId 49 | }); 50 | } 51 | res.send(note); 52 | }).catch(err => { 53 | if(err.kind === 'ObjectId') { 54 | return res.status(404).send({ 55 | message: "Note not found with id " + req.params.noteId 56 | }); 57 | } 58 | return res.status(500).send({ 59 | message: "Error retrieving note with id " + req.params.noteId 60 | }); 61 | }); 62 | }; 63 | 64 | // Update a note identified by the noteId in the request 65 | exports.update = (req, res) => { 66 | // Validate Request 67 | if(!req.body.content) { 68 | return res.status(400).send({ 69 | message: "Note content can not be empty" 70 | }); 71 | } 72 | 73 | // Find note and update it with the request body 74 | Note.findByIdAndUpdate(req.params.noteId, { 75 | title: req.body.title || "Untitled Note", 76 | content: req.body.content 77 | }, {new: true}) 78 | .then(note => { 79 | if(!note) { 80 | return res.status(404).send({ 81 | message: "Note not found with id " + req.params.noteId 82 | }); 83 | } 84 | res.send(note); 85 | }).catch(err => { 86 | if(err.kind === 'ObjectId') { 87 | return res.status(404).send({ 88 | message: "Note not found with id " + req.params.noteId 89 | }); 90 | } 91 | return res.status(500).send({ 92 | message: "Error updating note with id " + req.params.noteId 93 | }); 94 | }); 95 | }; 96 | 97 | // Delete a note with the specified noteId in the request 98 | exports.delete = (req, res) => { 99 | Note.findByIdAndRemove(req.params.noteId) 100 | .then(note => { 101 | if(!note) { 102 | return res.status(404).send({ 103 | message: "Note not found with id " + req.params.noteId 104 | }); 105 | } 106 | res.send({message: "Note deleted successfully!"}); 107 | }).catch(err => { 108 | if(err.kind === 'ObjectId' || err.name === 'NotFound') { 109 | return res.status(404).send({ 110 | message: "Note not found with id " + req.params.noteId 111 | }); 112 | } 113 | return res.status(500).send({ 114 | message: "Could not delete note with id " + req.params.noteId 115 | }); 116 | }); 117 | }; 118 | -------------------------------------------------------------------------------- /src/app/models/note.model.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | const NoteSchema = mongoose.Schema({ 4 | title: String, 5 | content: String 6 | }, { 7 | timestamps: true 8 | }); 9 | 10 | module.exports = mongoose.model('Note', NoteSchema); 11 | -------------------------------------------------------------------------------- /src/app/routes/note.routes.js: -------------------------------------------------------------------------------- 1 | module.exports = (app) => { 2 | const notes = require('../controllers/note.controller.js'); 3 | 4 | // Create a new Note 5 | app.post('/notes', notes.create); 6 | 7 | // Retrieve all Notes 8 | app.get('/notes', notes.findAll); 9 | 10 | // Retrieve a single Note with noteId 11 | app.get('/notes/:noteId', notes.findOne); 12 | 13 | // Update a Note with noteId 14 | app.put('/notes/:noteId', notes.update); 15 | 16 | // Delete a Note with noteId 17 | app.delete('/notes/:noteId', notes.delete); 18 | } 19 | -------------------------------------------------------------------------------- /src/config/database.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: 'mongodb://'+process.env.mongo_host+':'+process.env.mongo_port+'/easy-notes' 3 | } 4 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-express-crud", 3 | "version": "1.0.0", 4 | "description": "Node-Express-Crud", 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/badrinathpathak/Node-Express-Crud.git" 12 | }, 13 | "author": "", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/badrinathpathak/Node-Express-Crud/issues" 17 | }, 18 | "homepage": "https://github.com/badrinathpathak/Node-Express-Crud#readme", 19 | "dependencies": { 20 | "body-parser": "^1.19.0", 21 | "express": "^4.17.1", 22 | "mongoose": "^5.7.11" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const bodyParser = require('body-parser'); 3 | 4 | // create express app 5 | const app = express(); 6 | 7 | // parse requests of content-type - application/x-www-form-urlencoded 8 | app.use(bodyParser.urlencoded({ extended: true })) 9 | 10 | // parse requests of content-type - application/json 11 | app.use(bodyParser.json()) 12 | 13 | // Configuring the database 14 | const dbConfig = require('./config/database.config.js'); 15 | const mongoose = require('mongoose'); 16 | 17 | mongoose.Promise = global.Promise; 18 | 19 | // Connecting to the database 20 | mongoose.connect(dbConfig.url, { 21 | useNewUrlParser: true 22 | }).then(() => { 23 | console.log("Successfully connected to the database"); 24 | }).catch(err => { 25 | console.log('Could not connect to the database. Exiting now...', err); 26 | process.exit(); 27 | }); 28 | 29 | 30 | // define a simple route 31 | app.get('/', (req, res) => { 32 | res.json({"message": "Welcome to EasyNotes application. Take notes quickly. Organize and keep track of all your notes."}); 33 | }); 34 | require('./app/routes/note.routes.js')(app); 35 | // listen for requests 36 | app.listen(process.env.node_port, () => { 37 | console.log("Server is listening on port ",process.env.node_port); 38 | }); 39 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | /usr/local/bin/node /usr/src/app/CRUD-API-Node.js-Express-and-MongoDB/src/server.js 4 | --------------------------------------------------------------------------------