├── dist └── Untitled Document ├── routes ├── index.js └── users.js ├── models └── User.js ├── config └── db.js ├── server.js ├── router.js ├── simple_bookshelf.sql ├── package.json ├── public ├── userDetails.html ├── userList.html ├── index.html ├── app.js └── addUser.html └── README.md /dist/Untitled Document: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | var index = function (req, res) { 4 | res.sendFile(path.resolve(__dirname + '/../public/index.html')); 5 | }; 6 | 7 | module.exports.index = index; -------------------------------------------------------------------------------- /models/User.js: -------------------------------------------------------------------------------- 1 | var bookshelf = require('./../config/db').bookshelf; 2 | 3 | var User = bookshelf.Model.extend({ 4 | tableName: 'users' 5 | }); 6 | 7 | module.exports = { 8 | User: User 9 | }; 10 | -------------------------------------------------------------------------------- /config/db.js: -------------------------------------------------------------------------------- 1 | var DBConfig = { 2 | client: 'mysql', 3 | connection: { 4 | host: 'localhost', 5 | user: 'root', 6 | password: 'mendim', 7 | database: 'simple_bookshelf', 8 | charset: 'utf8' 9 | } 10 | }; 11 | 12 | var knex = require('knex')(DBConfig); 13 | var bookshelf = require('bookshelf')(knex); 14 | 15 | module.exports.bookshelf = bookshelf; 16 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | var bodyParser = require('body-parser'); 4 | 5 | app.use(bodyParser.json()); 6 | app.use('/public', express.static(__dirname + '/public')); 7 | 8 | /* Router */ 9 | require('./router')(app); 10 | 11 | app.listen(3000, function () { 12 | console.log('Go to localhost:3000'); 13 | }); 14 | 15 | -------------------------------------------------------------------------------- /router.js: -------------------------------------------------------------------------------- 1 | var user = require('./routes/users'); 2 | var index = require('./routes/index'); 3 | 4 | module.exports = function (app) { 5 | 6 | /* Index(main) route */ 7 | app.get('/', index.index); 8 | 9 | /* User Routes */ 10 | app.post('/users', user.saveUser); 11 | app.get('/users', user.getAllUsers); 12 | app.delete('/user/:id', user.deleteUser); 13 | app.get('/user/:id', user.getUser); 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /simple_bookshelf.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE `simple_bookshelf` ; 2 | 3 | use simple_bookshelf; 4 | 5 | CREATE TABLE `users` ( 6 | `id` int(11) NOT NULL AUTO_INCREMENT, 7 | `username` varchar(100) DEFAULT NULL, 8 | `email` varchar(100) DEFAULT NULL, 9 | `name` varchar(100) DEFAULT NULL, 10 | `age` int(11) DEFAULT NULL, 11 | `location` varchar(100) DEFAULT NULL, 12 | PRIMARY KEY (`id`) 13 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 14 | 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simplebookshelfapp", 3 | "version": "1.0.0", 4 | "description": "Simple Bookshelf App made to see how bookshelf works", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Mendim Mestani", 10 | "license": "ISC", 11 | "dependencies": { 12 | "body-parser": "^1.10.0", 13 | "bookshelf": "^0.7.9", 14 | "express": "^4.10.4", 15 | "knex": "^0.7.3", 16 | "mysql": "^2.5.3", 17 | "path": "^0.4.9" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /public/userDetails.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Details for user called {{user.name}}

4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
Username{{user.username}}
Email{{user.email}}
Name{{user.name}}
Age{{user.age}}
Location{{user.location}}
30 |
31 | 32 |
-------------------------------------------------------------------------------- /public/userList.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |

List of Users

4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 |
UsernameEmailNameAgeLocationAction
{{ user.username }}{{ user.email }}{{ user.name }}{{ user.age }}{{ user.location }} 25 | 26 |
31 |
-------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Simple Bookshelf App 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /routes/users.js: -------------------------------------------------------------------------------- 1 | var Model = require('./../models/User'); 2 | 3 | /* Save a user */ 4 | var saveUser = function (req, res) { 5 | new Model.User({ 6 | username: req.body.username, 7 | email: req.body.email, 8 | name: req.body.name, 9 | age: req.body.age, 10 | location: req.body.location 11 | }).save() 12 | .then(function (user) { 13 | res.json(user); 14 | }).catch(function (error) { 15 | console.log(error); 16 | res.send('An error occured'); 17 | }); 18 | }; 19 | 20 | /* Get all users */ 21 | var getAllUsers = function (req, res) { 22 | new Model.User().fetchAll() 23 | .then(function (users) { 24 | res.json(users); 25 | }).catch(function (error) { 26 | console.log(error); 27 | res.send('An error occured'); 28 | }); 29 | }; 30 | 31 | /* Delete a user */ 32 | var deleteUser = function (req, res) { 33 | var userId = req.params.id; 34 | new Model.User().where('id', userId) 35 | .destroy() 36 | .catch(function (error) { 37 | console.log(error); 38 | res.send('An error occured'); 39 | }); 40 | }; 41 | 42 | /* Get a user */ 43 | var getUser = function (req, res) { 44 | var userId = req.params.id; 45 | new Model.User().where('id', userId) 46 | .fetch() 47 | .then(function (user) { 48 | res.json(user); 49 | }).catch(function (error) { 50 | console.log(error); 51 | res.send('An error occured'); 52 | }); 53 | }; 54 | 55 | /* Exports all methods */ 56 | module.exports = { 57 | saveUser: saveUser, 58 | getAllUsers: getAllUsers, 59 | deleteUser: deleteUser, 60 | getUser: getUser 61 | }; 62 | -------------------------------------------------------------------------------- /public/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('simpleBookshelfApp', ['ngResource', 'ngRoute']) 4 | .config(function ($routeProvider, $httpProvider) { 5 | 6 | $routeProvider.when('/user-list', {templateUrl: 'public/userList.html', controller: 'UserCtrl'}); 7 | $routeProvider.when('/add-user', {templateUrl: 'public/addUser.html', controller: 'UserCtrl'}); 8 | $routeProvider.when('/user-details/:id', { 9 | templateUrl: 'public/userDetails.html', 10 | controller: 'UserDetailsCtrl' 11 | }); 12 | $routeProvider.otherwise({redirectTo: '/user-list'}); 13 | }) 14 | .factory('UsersFactory', function ($resource) { 15 | return $resource('/users', {}, { 16 | addUser: {method: 'POST'}, 17 | listUsers: {method: 'GET', isArray: true} 18 | }) 19 | }) 20 | .factory('UserFactory', function ($resource) { 21 | return $resource('/user/:id', {}, { 22 | deleteUser: {method: 'DELETE', params: {id: '@id'}}, 23 | userDetails: {method: 'GET', params: {id: '@id'}} 24 | }) 25 | }) 26 | .controller('UserCtrl', ['$scope', 'UserFactory', 'UsersFactory', '$location', 27 | function ($scope, UserFactory, UsersFactory, $location) { 28 | $scope.addNewUser = function () { 29 | UsersFactory.addUser($scope.user); 30 | $location.path('/user-list'); 31 | }; 32 | 33 | $scope.deleteUser = function (userId) { 34 | UserFactory.deleteUser({id: userId}); 35 | $scope.users = UsersFactory.listUsers(); 36 | }; 37 | 38 | $scope.users = UsersFactory.listUsers(); 39 | 40 | }]) 41 | .controller('UserDetailsCtrl', ['$scope', '$routeParams', 'UsersFactory', '$location', 42 | function ($scope, $routeParams, UserFactory, $location) { 43 | $scope.userDetails = function () { 44 | $location.path('/user-details'); 45 | }; 46 | $scope.user = UserFactory.userDetails({id: $routeParams.id}); 47 | 48 | 49 | }]); 50 | -------------------------------------------------------------------------------- /public/addUser.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Add new User

4 |
5 | 6 |
7 |
8 |
9 | 10 | 11 |
12 | 14 |
15 |
16 | 17 |
18 | 19 | 20 |
21 | 22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 | 30 |
31 |
32 | 33 |
34 | 35 | 36 |
37 | 38 |
39 |
40 | 41 |
42 | 43 | 44 |
45 | 47 |
48 |
49 | 50 |
51 |
52 | 53 |
54 |
55 |
56 |
57 |
-------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Simple Application that uses Node.js(Express) and Bookshelf.js ORM 2 | ================================================================== 3 | 4 | 5 | ### Description 6 | 7 | This is a simple application that implements bookshelf.js JavaScript ORM(Object Relational Mapping) with Node.js 8 | 9 | There is included an example that create, list, delete and list details of an user. 10 | 11 | 12 | ### File Structure 13 | 14 | simpleBookshelfApp/ - Location for simpleBookshelfApp specific files. 15 | simpleBookshelfApp/config/ - Location for configuration files. 16 | simpleBookshelfApp/config/db.js - Database configuratin file. 17 | simpleBookshelfApp/models/ - Location for Models. 18 | simpleBookshelfApp/models/User.js - User model file. 19 | simpleBookshelfApp/public/ - Location for all client-side code (views, assets(js, css etc)) 20 | simpleBookshelfApp/routes/ - Location for application logic. 21 | simpleBookshelfApp/routes/index.js - Main source 22 | simpleBookshelfApp/routes/users.js - User logic. 23 | simpleBookshelfApp/router.js - Application router. 24 | package.json - npm package descriptor. 25 | server.js - Main application file. 26 | README.md - This file. 27 | 28 | 29 | ### Packages (package.json) 30 | 31 | This store node modules dependencies used in application. 32 | 33 | express(v4.10.4) - This package is a MVC framework for Node.js 34 | bookshelf(v0.4.9) - This package is javascript ORM for Node.js 35 | knex(v0.7.3) - This package is for SQL Query Builder for Postgrate, MySQL etc. 36 | mysql(v2.5.3) - This package is a MySQL driver for Node.js 37 | body-parse(v1.10.0) - This package is a Node.js body parser 38 | path(v0.4.9) - This package is a Node.js path module 39 | 40 | All these package are installed by ```npm```(Node Package Manager). You have to type ```npm install``` at directory package.json is stored and all packages will be installed automatically. 41 | 42 | 43 | ### Code description 44 | 45 | 1. In the ```config/db.js``` is stored database configuration, 46 | 47 | First, there is declared an object ```DBConfig```, in this object are stored data for database client and database options 48 | 49 | ```javascript 50 | var DBConfig = { 51 | client: 'mysql', 52 | connection: { 53 | host: 'localhost', 54 | user: 'root', 55 | password: 'mysql_password', 56 | database: 'database_name', 57 | charset: 'utf8' 58 | } 59 | }; 60 | ``` 61 | Then, there is included ```knex``` package passing ```DBConfig``` object, after that there is included ```bookshelf``` package passing ```knex``` 62 | ```javascript 63 | var knex = require('knex')(DBConfig); 64 | var bookshelf = require('bookshelf')(knex); 65 | ``` 66 | 67 | And finally, is exported ```bookshelf``` and we are done with ```config/db.js``` file. 68 | ```javascript 69 | module.exports.bookshelf = bookshelf; 70 | ``` 71 | 72 | 2. Let's describe next file ```models/User.js``` 73 | 74 | First, is included ```bookshelf``` that we exported above 75 | 76 | ```javascript 77 | var bookshelf = require('./../config/db').bookshelf; 78 | ``` 79 | Then,is declared a ```User``` object that extends built-in ```bookshelf Model``` with a table name, in this case ```users``` table 80 | 81 | ```javascript 82 | var User = bookshelf.Model.extend({ 83 | tableName: 'users' 84 | }); 85 | ``` 86 | Finally, export ```User``` and we are done with model. 87 | ```javascript 88 | module.exports = { 89 | User: User 90 | }; 91 | ``` 92 | 93 | 3. The directory ```routes``` contains two files: ```index.js``` and ```users.js```. 94 | 95 | In index.js, first is included ```path``` package needed resolve relative path. Then, we export the main view file (index.html). 96 | ```javascript 97 | var path = require('path'); 98 | 99 | var index = function (req, res) { 100 | res.sendFile(path.resolve(__dirname + '/../public/index.html')); 101 | }; 102 | 103 | module.exports.index = index; 104 | ``` 105 | 106 | Code below belongs to ```users.js``` file. First of all, there is included User model. 107 | To save a user, inputs are set by a request from client side, and with ```save``` method of ```bookshelf``` it is saved to db. If it will be saved, ```then``` method repond user as ```json```, othervise it fires and error. 108 | 109 | ```javascript 110 | var Model = require('./../models/User'); 111 | 112 | /* Save a user */ 113 | var saveUser = function (req, res) { 114 | new Model.User({ 115 | username: req.body.username, 116 | email: req.body.email, 117 | name: req.body.name, 118 | age: req.body.age, 119 | location: req.body.location 120 | }).save() 121 | .then(function (user) { 122 | res.json(user); 123 | }).catch(function (error) { 124 | res.json(error); 125 | }); 126 | }; 127 | ``` 128 | 129 | Below are returnded all users from database, useing another method of ```bookshelf - fetchAll()```. 130 | ```javascript 131 | /* Get all users */ 132 | var getAllUsers = function (req, res) { 133 | new Model.User().fetchAll() 134 | .then(function (users) { 135 | res.json(users); 136 | }).catch(function (error) { 137 | res.json(error); 138 | }); 139 | }; 140 | ``` 141 | 142 | First, this get the user id from url parameters and then using ```destroy``` method, it deletes the user in database. 143 | ```javascript 144 | /* Delete a user */ 145 | var deleteUser = function (req, res) { 146 | var userId = req.params.id; 147 | new Model.User().where('id', userId) 148 | .destroy() 149 | .catch(function (error) { 150 | res.json(error); 151 | }); 152 | }; 153 | ``` 154 | 155 | The code below gets all details for a specified user. 156 | ```javascript 157 | /* Get a user */ 158 | var getUser = function (req, res) { 159 | var userId = req.params.id; 160 | new Model.User().where('id', userId) 161 | .fetch() 162 | .then(function (user) { 163 | res.json(user); 164 | }).catch(function (error) { 165 | res.json(error); 166 | }); 167 | }; 168 | ``` 169 | 170 | Using ```module.export``` it exports all methods explained above. 171 | ```javascript 172 | /* Exports all methods */ 173 | module.exports = { 174 | saveUser: saveUser, 175 | getAllUsers: getAllUsers, 176 | deleteUser: deleteUser, 177 | getUser: getUser 178 | }; 179 | ``` 180 | 181 | 4. router.js 182 | 183 | This is router. It included logic from routes collection and uses methods from these routes, and at least it export url routes for basic http methods using expressjs. This method will be used to ```server.js``` 184 | 185 | ```javascript 186 | 187 | var user = require('./routes/users'); 188 | var index = require('./routes/index'); 189 | 190 | module.exports = function (app) { 191 | 192 | /* Index(main) route */ 193 | app.get('/', index.index); 194 | 195 | /* User Routes */ 196 | app.post('/users', user.saveUser); 197 | app.get('/users', user.getAllUsers); 198 | app.delete('/user/:id', user.deleteUser); 199 | app.get('/user/:id', user.getUser); 200 | }; 201 | ``` 202 | 203 | 5. server.js 204 | 205 | Here the server is started and the routes are called. The ```express``` framework and ```body-parser``` are included. ```body-parser``` is used to parse ```json```. 206 | 207 | ```javascript 208 | var express = require('express'); 209 | var app = express(); 210 | var bodyParser = require('body-parser'); 211 | 212 | app.use(bodyParser.json()); 213 | app.use('/public', express.static(__dirname + '/public')); 214 | 215 | /* Router */ 216 | require('./router')(app); 217 | 218 | app.listen(3000, function () { 219 | console.log('Go to localhost:3000'); 220 | }); 221 | ``` 222 | 223 | Finally the simple app is done. Enjoy it! 224 | --------------------------------------------------------------------------------