Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/easingthemes/simple-nodejs
Simple nodejs crud
https://github.com/easingthemes/simple-nodejs
Last synced: 21 days ago
JSON representation
Simple nodejs crud
- Host: GitHub
- URL: https://github.com/easingthemes/simple-nodejs
- Owner: easingthemes
- Created: 2015-09-13T11:43:44.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2015-09-13T11:58:34.000Z (over 9 years ago)
- Last Synced: 2024-10-15T20:07:04.262Z (2 months ago)
- Language: JavaScript
- Size: 203 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## If you want to try it
Start mongodb
```
mongod
```
start project
```
git clone https://github.com/easingthemes/restapi.git
cd restapi
npm install
grunt serve
```
## If you want to learn
Follow this readme and build your app from scratch.If you use Grunt and Node modules for front-end, but you never tried server side javaScript, this tutorial is for you.
App is based on Yeoman generator angular-fullstack, but simplified a lot, and without Angular :). This is great intro for diving deeper in Angular and MEAN stack.
Actually this project helped me alot to finally understand some aspects of back-end development, and to separate Angular from Node.
## Tools list
nodejs, mongodb, grunt## Scafold project directories and files
```
server/
server.js
routes.js
api/client/
index.html
js/
app.js
lib/
jquery.js
```Include app.js and jquery.js in index.html. Write down some text on the page.
```
client/
index.html
```
`Hello API
`## Install extensions
####1. Create `project.json` file`npm init`
####1. Create `Gruntfile.js` file
Gruntfile.js
####2. Install node modules
`npm install express mongoose body-parser lodash --save`
####3. Install Dev modules for Grunt tasks
`npm install grunt-contrib-watch grunt-express-server grunt-open --save-dev`
## SERVER: express server configuration
####1. Configure server
file: `server/server.js`
Include modules and define basic variables
```
var express = require("express"),
server = express(),
hostname = 'localhost',
port = 3000;
```Now use them:
```
server.use(express.static(__dirname + '/../app'));
server.listen(port, hostname);
console.log("Server listening: http://" + hostname + ":" + port);
```####2. Create GRUNT tasks for express server
```
module.exports = function(grunt) {grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-express-server');
grunt.loadNpmTasks('grunt-open');grunt.initConfig({
watch: {
express: {
files: [ '**/*.js' ],
tasks: [ 'express:dev' ],
options: {
spawn: false
}
}
},
express: {
options: {
port: 3000
},
dev: {
options: {
script: 'server/server.js',
debug: true
}
}
},
open: {
dev: {
path: 'http://localhost:<%= express.options.port%>'
}
}});
grunt.registerTask('serve', [ 'express:dev', 'open:dev', 'watch' ])
};
```####3. Test express server
`grunt serve`Browser should open configured location and you should see `hello api` page.
There should also be log in the terminal:
`Server: Express listening: http://localhost:3000`## DATABASE: MongoDB configuration
####1. Configure mongoose for MongoDB
```
server/
server.js
```
Stop server first `CTRL + C`
Include new modules```
var express = require("express"),
mongoose = require('mongoose'),
bodyParser = require('body-parser'),
...
```
We need `mongoose` for `mongodb` manipulation and `body-parser` for sending and receiving JSON data.So let's use them:
```
app.use(express.static(__dirname + '/../app'));
app.use(bodyParser.json());
...
```
Mongoose connect
```
mongoose.connect('mongodb://localhost/simple', function(err) {
if(err) {
console.log('connection error', err);
} else {
console.log('connection successful');
}
});
```
####2. Start `mongod` process
`mongod`
On Windows just doubleclick `mongod.exe`
####3. Test DB connection
Start server again
`grunt serve`
There should be new log
`Database: MongoDB connection successful`## API Routes
####1. Create folder for your API
```
server/
api/
item/
```
####2. MODEL: Create DataBase Schema
```
item/
item.model.js
```
Schema types: http://mongoosejs.com/docs/schematypes.html
```
var mongoose = require('mongoose'),
Schema = mongoose.Schema;var ItemSchema = new Schema({
title: String,
date: Date
});module.exports = mongoose.model('Item', ItemSchema);
```
####3. CONTROLLER: Create functions for DATABASE manipulation - CRUD: Create Read Update Delete
```
item/
item.controller.js
```
```
// Import model
var Item = require('./item.model');
// READ: Get list of Items
exports.index = function(req, res) {
Item.find(function (err, items) {
if(err) { return handleError(res, err); }
return res.status(200).json(items);
});
};
```
####4. ROUTES: Define API router
```
item/
index.js
```
```
// Import extensions
var express = require('express'),
controller = require('./item.controller');
// Define router
var router = express.Router();
// Define routes
router.get('/', controller.index);// Export module
module.exports = router;
```
####5. ROUTES: Create server routes
```
server/
routes.js
```
```
module.exports = function(server) {
server.use('/api/items', require('./api/item'));
// All other routes should redirect to the index.html
server.route('/*')
.get(function(req, res) {
res.sendfile('app/index.html');
});
};
```
####6. Test API routes
`http://localhost:3000/api/items`
You should se empty array, since DB is empty.
`[]`## CRUD - Create Read Update Delete
1. CONTROLLER: Create functions for DB manipulation - CRUD
2. ROUTER: Create API router#### CONTROLLER: Create functions for DB manipulation - CRUD
We need `body-parser` mongoose module to pars JSON. Add it to `server.js`
```
server/
server.js
```
```
var express = require("express"),
mongoose = require('mongoose'),
bodyParser = require('body-parser'),
server = express(),
hostname = 'localhost',
port = 3000;server.use(express.static(__dirname + '/../client'));
server.use(bodyParser.json());
...
```
```
item/
item.controller.js
```
```
// Get list of Items
exports.index = function(req, res) {
Item.find(function (err, items) {
if(err) { return handleError(res, err); }
return res.status(200).json(items);
});
};
// Get a single item
exports.show = function(req, res) {
Item.findById(req.params.id, function (err, item) {
if(err) { return handleError(res, err); }
if(!item) { return res.sendStatus(404); }
return res.json(item);
});
};
//Creates a new item in the DB.
exports.create = function(req, res) {
Item.create(req.body, function(err, item) {
if(err) { return handleError(res, err); }
return res.status(201).json(item);
});
};
// Updates an existing item in the DB.
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
Item.findById(req.params.id, function (err, item) {
if (err) { return handleError(res, err); }
if(!item) { return res.send(404); }
var updated = _.merge(item, req.body);
updated.save(function (err) {
if (err) { return handleError(res, err); }
return res.json(200, item);
});
});
};
// Deletes a item from the DB.
exports.delete = function(req, res) {
Item.findById(req.params.id, function (err, item) {
if(err) { return handleError(res, err); }
if(!item) { return res.sendStatus(404); }
item.remove(function(err) {
if(err) { return handleError(res, err); }
return res.sendStatus(204);
});
});
};
```
#### ROUTER: Create API router
```
router.get('/', controller.index);
router.get('/:id', controller.show);
router.post('/', controller.create);
router.put('/:id', controller.update);
router.patch('/:id', controller.update);
router.delete('/:id', controller.delete);
```## CLIENT: use created CRUD functions from frontend
####1. For some methods we need `lodash` module
`npm install lodash --save`
Add it to
```
item/
item.controller.js
```
```
var Item = require('./item.model');
var _ = require('lodash');
```
####2. Create DOM
```
client/
index.html
```
```hello api
Create item
```
####3. Create javaScript functions
```
client/
js/
app.js
```
```
app = {
init: function(){
app.showPosts();
$(document).on('click', 'button', function(event) {
event.preventDefault();
var itemTitle = $('input').val();
var jsonItem = JSON.stringify({title: itemTitle});
app.createPost(jsonItem);
});
$(document).on('click', 'a', function(event) {
event.preventDefault();
app.deletePost($(this).parent().attr('id'));
});
$('ul').on('click', 'li', function(event) {
app.showPost($(this).attr('id'));
});
$(document).on('click', 'span', function(event) {
var newTitle = $(this).siblings('p').text();
var jsonItem = JSON.stringify({title: newTitle});
app.updatePost($(this).parent().data('id'), jsonItem);
});
},
showPosts: function(){
//READ: get all items from API uri
$.get('/api/items', function(data) {
$.each(data, function(index, val) {
$('
'+val.title+'
delete});
});
},
showPost: function(itemId){
//GET: get single item from API uri
$.get('/api/items/'+itemId, function(data) {
$('
'+data.title+'
edit});
},
createPost: function(data){
//CREATE: create new item
$.ajax({
url: '/api/items',
type: 'POST',
contentType: 'application/json',
dataType: 'json',
data: data
})
.done(function(data) {
$('
'+data.title+'
});
},
updatePost: function(itemId, newData){
//UPDATE: update item
$.ajax({
url: '/api/items/'+itemId,
type: 'PUT',
contentType: 'application/json',
dataType: 'json',
data: newData
})
.done(function(data) {
console.log(data._id+' - '+data.title);
$('#'+data._id+' p').text(data.title);
});
},
deletePost: function(itemId){
//DELETE: delete item
$.ajax({
url: '/api/items/'+itemId,
type: 'DELETE'
});
var itemElement = document.getElementById(itemId);
itemElement.parentNode.removeChild(itemElement);
}
}
jQuery(document).ready(function($) {
app.init();
});
```
#### DONE:
*Starring*: nodejs with express, mongodb with mongoose
*Also Starring**: Grunt
*Thanks to*: body-parser, lodash, grunt-contrib-watch, grunt-express-server and grunt-open