Sunday, February 18, 2018

ER Diagram

ER diagram was proposed by Peter Chen in 1976. ER diagram is widely used in database design. Represent conceptual level of a database system

This is a flowchart represents relationship between two entities.

ER Diagrams are most often used to design or debug relational databases in the fields of software engineering, business information systems, education and research.

Attributes: Common properties of the entities in a entity sets. Attributes are represented by means of ellipses. Every ellipse represents one attribute and is directly connected to its entity.

Attributes
Composite VS Simple Attributes
Single valued VS Multivalued Attributes
Stored VS Derived Attributes
Complex Attributes

Attributes: If the attributes are composite, they are further
divided in a tree like structure. Every node is then connected to
its attribute. That is, composite attributes are represented by
ellipses that are connected with an ellipse.

Relationship – specify the relations among entities from
two or more entity sets

A relationship where two entities are participating is
called a binary relationship. Cardinality is the number of
instance of an entity from a relation that can be
associated with the relation.

One-to-one
One-to-many
many-to-one
many-to-many

Participation Constraints
Basic concepts
Total Participation − Each entity is involved in
the relationship. Total participation is
represented by double lines.

Partial participation − Not all entities are
involved in the relationship. Partial participation
is represented by single lines

Key is an attribute or collection of attributes that uniquely
identifies an entity among entity set.

Keys
Super Key − A set of attributes (one or more) that
collectively identifies an entity in an entity set.

Candidate Key − A minimal super key is called a
candidate key. An entity set may have more than one
candidate key.

Primary Key − A primary key is one of the candidate keys
chosen by the database designer to uniquely identify the
entity set.

Node Authentication

For allowing users to sign up & login we will use Authentication method using node, express & mongoose. We have to include Facebook, Twitter & Google Authentication also.

So,that we have to create a new folder to do this authentication & execute. The following is the tree diagram of how the folder looks..

- app
------ models
---------- user.js <!-- our user model -->
 ------ routes.js <!-- all the routes for our application -->
- config
------ auth.js <!-- will hold all our client secret keys (facebook, twitter, google) --> ------ database.js <!-- will hold our database connection settings -->
------ passport.js <!-- configuring the strategies for passport -->
- views
------ index.ejs <!-- show our home page with login links -->
------ login.ejs <!-- show our login form -->
------ signup.ejs <!-- show our signup form -->
------ profile.ejs <!-- after a user logs in, they will see their profile -->

- package.json <!-- handle our npm packages -->
- server.js <!-- setup our application -->

We will use some dependencies of Node to do this authentication
  1. passport - To authenticate local sign in & sign up & social media oAuth
  2. bcrypt Node - To hash the password (Then only, the password will be stored as an encrypted form in database.
  3. connect-flash - To flash messages in the login & sign up forms to show the user that he/she input wrong email/password
  4. express - framework of nodejs
  5. mongoose - Object modelling for mongo DB
  6. ejs - templating engine
  7.  
Now we have to create package.json to require our dependencies..

{
"name": "node-authentication",
"main": "server.js",
"dependencies" :
{
 "express" : "~4.14.0",
"ejs" : "~2.5.2",
"mongoose" : "~4.13.1",
"passport" : "~0.3.2",
"passport-local" : "~1.0.0",
"passport-facebook" : "~2.1.1",
"passport-twitter" : "~1.0.4",
"passport-google-oauth" : "~1.0.0",
"connect-flash" : "~0.1.1",
"bcrypt-nodejs" : "latest",
"morgan": "~1.7.0",
"body-parser": "~1.15.2",
"cookie-parser": "~1.4.3",
"method-override": "~2.3.6",
"express-session": "~1.14.1"
}
}

now we have to install the above dependencies in our app folder
to do type
npm install

Now Server.js

// set up ============================================ // get all the tools we need
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var configDB = require('./config/database.js'); // configuration ============================================ mongoose.connect(configDB.url); // connect to our database //
require('./config/passport')(passport); // pass passport for configuration
// set up our express application
app.use(morgan('dev')); // log every request to the console app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser()); // get information from html forms
app.set('view engine', 'ejs'); // set up ejs for templating
// required for passport
app.use(session({ secret: 'ilovescotchscotchyscotchscotch' })); // session secret app.use(passport.initialize()); app.use(passport.session()); // persistent login sessions app.use(flash()); // use connect-flash for flash messages stored in session // routes =========================================
require('./app/routes.js')(app, passport); // load our routes and pass in our app and fully configured passport // launch =============================================== app.listen(port); console.log('The magic happens on port ' + port);

In config/database.js we have to add this code

module.exports = {
 'url' : 'your-settings-here' // looks like mongodb://<user>:<pass>@mongo.onmodulus.net:27017/Mikha4ot };
};

We will include the routing code


In app/routes.js
module.exports = function(app, passport) {

    // =====================================
    // HOME PAGE (with login links) ========
    // =====================================
    app.get('/', function(req, res) {
        res.render('index.ejs'); // load the index.ejs file
    });

    // =====================================
    // LOGIN ===============================
    // =====================================
    // show the login form
    app.get('/login', function(req, res) {

        // render the page and pass in any flash data if it exists
        res.render('login.ejs', { message: req.flash('loginMessage') }); 
    });

    // process the login form
    // app.post('/login', do all our passport stuff here);

    // =====================================
    // SIGNUP ==============================
    // =====================================
    // show the signup form
    app.get('/signup', function(req, res) {

        // render the page and pass in any flash data if it exists
        res.render('signup.ejs', { message: req.flash('signupMessage') });
    });

    // process the signup form
    // app.post('/signup', do all our passport stuff here);

    // =====================================
    // PROFILE SECTION =====================
    // =====================================
    // we will want this protected so you have to be logged in to visit
    // we will use route middleware to verify this (the isLoggedIn function)
    app.get('/profile', isLoggedIn, function(req, res) {
        res.render('profile.ejs', {
            user : req.user // get the user out of session and pass to template
        });
    });

    // =====================================
    // LOGOUT ==============================
    // =====================================
    app.get('/logout', function(req, res) {
        req.logout();
        res.redirect('/');
    });
};

// route middleware to make sure a user is logged in
function isLoggedIn(req, res, next) {

    // if user is authenticated in the session, carry on 
    if (req.isAuthenticated())
        return next();

    // if they aren't redirect them to the home page
    res.redirect('/');
}

Sunday, February 11, 2018

Heroku


Heroku is a cloud platform as a service (PaaS) supporting several programming languages that is used as a web application deployment model.
Heroku, one of the first cloud platforms, has been in development since June 2007, when it supported only the Ruby programming language, but now supports Java, Node.js, Scala, Clojure, Python, PHP.

For this reason, Heroku is said to be a polyglot platform as it lets the developer build, run and scale applications in a similar manner across all the languages. Heroku was acquired by Salesforce.com in 2010 for $212 million.

Install Heroku

# Run this from your terminal.
# The following will add our apt repository and install the CLI:

sudo add-apt-repository "deb https://cli-assets.heroku.com/branches/stable/apt ./"

curl -L https://cli-assets.heroku.com/apt/release.key | sudo apt-key add -

sudo apt-get update

sudo apt-get install heroku

Check installation success by typing -> heroku --version
 
Signup for Heroku - https://www.heroku.com/ 
Signup for mLab - https://mlab.com

Add (specify version of node) to package.json

"engines": {
    "node": "6.10.1"
 }

Add Procfile to root
web: node server.js

Add .gitignore file to root
/node_modules
npm-debug.log
.DS_Store
/*.env

Change Port  on server.js
const port = process.env.PORT || 8000;

Build and run locally
npm install
heroku local web
Deploy your application to Heroku
git init
git add .
git commit -m "first commit"
git status
heroku login
Enter your Heroku credentials.
...

heroku create ukifunwork2byname

git push heroku master

Optional  (if above fails)- Add heroku git remote
heroku git:remote -a yourapp
And retry git push heroku master

heroku open

For Logging
heroku logs --tail

Mongoose API

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.
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.
Finally, we’ll test our REST APIs using Postman.
Well! Now that we know what we are going to build, We need a cool name for our application. Let’s call our application EasyNotes.

Creating the Application

1. Fire up your terminal and create a new folder for the application.
$ mkdir node-easy-notes-app
2. Initialize the application with a package.json file
Go to the root folder of your application and type npm init to initialize your app with a package.json file.
$ cd node-easy-notes-app
$ npm init
name: (node-easy-notes-app)
version: (1.0.0)
description: Never miss a thing in Life. Take notes quickly. Organize and keep track of all your notes.
entry point: (index.js) server.js
test command:
git repository:
keywords: Express RestAPI MongoDB Mongoose Notes
author: callicoder
license: (ISC) MIT
About to write to /Users/rajeevkumarsingh/node-easy-notes-app/package.json:

{
 "name": "node-easy-notes-app",
 "version": "1.0.0",
 "description": "Never miss a thing in Life. Take notes quickly. Organize and keep track of all your notes.",
 "main": "server.js",
 "scripts": {
   "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [
   "Express",
   "RestAPI",
   "MongoDB",
   "Mongoose",
   "Notes"
 ],
 "author": "callicoder",
 "license": "MIT"
}

Is this ok? (yes) yes
Note that I’ve specified a file named server.js as the entry point of our application. We’ll create server.js file in the next section.
3. Install dependencies
We will need express, mongoose and body-parser modules in our application. Let’s install them by typing the following command -
$ npm install express body-parser mongoose --save
I’ve used --save option to save all the dependencies in the package.json file. The final package.json file looks like this -

{
 "name": "node-easy-notes-app",
 "version": "1.0.0",
 "description": "Never miss a thing in Life. Take notes quickly. Organize and keep track of all your notes.",
 "main": "server.js",
 "scripts": {
   "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [
   "Express",
   "RestAPI",
   "MongoDB",
   "Mongoose",
   "Notes"
 ],
 "author": "callicoder",
 "license": "MIT",
 "dependencies": {
   "body-parser": "^1.18.2",
   "express": "^4.16.2",
   "mongoose": "^4.13.6"
 }
}
Our application folder now has a package.json file and a node_modules folder -
node-easy-notes-app
   └── node_modules/
   └── package.json

Setting up the web server

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 -

var express = require('express');
var bodyParser = require('body-parser');

// create express app
var app = express();

// parse requests of content-type - application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }))

// parse requests of content-type - application/json
app.use(bodyParser.json())

// define a simple route
app.get('/', function(req, res){
   res.json({"message": "Welcome to EasyNotes application. Take notes quickly. Organize and keep track of all your notes."});
});

// listen for requests
app.listen(3000, function(){
   console.log("Server is listening on port 3000");
});
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.
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.
Then, We define a simple GET route which returns a welcome message to the clients.
Finally, We listen on port 3000 for incoming connections.
All right! Let’s now run the server and go to http://localhost:3000 to access the route we just defined.
$ node server.js
Server is listening on port 3000

Configuring and Connecting to the database

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 -
$ mkdir config
$ cd config
Now, Create a new file database.config.js inside config folder with the following contents -
module.exports = {
   url: 'mongodb://localhost:27017/easy-notes'
}
We’ll now import the above database configuration in server.js and connect to the database using mongoose.
Add the following code to the server.js file after app.use(bodyParser.json()) line -
// Configuring the database
var dbConfig = require('./config/database.config.js');
var mongoose = require('mongoose');

mongoose.connect(dbConfig.url, {
   useMongoClient: true
});

mongoose.connection.on('error', function() {
   console.log('Could not connect to the database. Exiting now...');
   process.exit();
});

mongoose.connection.once('open', function() {
   console.log("Successfully connected to the database");
})
Please run the server and make sure that you’re able to connect to the database -
$ node server.js
Server is listening on port 3000
Successfully connected to the database

Defining the Note model in Mongoose

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 -
$ mkdir -p app/models
$ cd app/models
Now, create a file called note.model.js inside app/models folder with the following contents -

var mongoose = require('mongoose');

var NoteSchema = mongoose.Schema({
   title: String,
   content: String
}, {
   timestamps: true
});

module.exports = mongoose.model('Note', NoteSchema);
The Note model is very simple. It contains a title and a content field. I have also added a timestamps option to the schema.
Mongoose uses this option to automatically add two new fields - createdAt and updatedAt to the schema.

Defining Routes using Express

Next up is the routes for the Notes APIs. Create a new folder called routes inside the app folder.
$ mkdir app/routes
$ cd app/routes
Now, create a new file called note.routes.js inside app/routes folder with the following contents -

module.exports = function(app) {

   var notes = require('../controllers/note.controller.js');

   // Create a new Note
   app.post('/notes', notes.create);

   // Retrieve all Notes
   app.get('/notes', notes.findAll);

   // Retrieve a single Note with noteId
   app.get('/notes/:noteId', notes.findOne);

   // Update a Note with noteId
   app.put('/notes/:noteId', notes.update);

   // Delete a Note with noteId
   app.delete('/notes/:noteId', notes.delete);
}
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.
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.
// ........

// Require Notes routes
require('./app/routes/note.routes.js')(app);

// ........
If you run the server now, you’ll get the following error -
$ node server.js
module.js:472
   throw err;
   ^

Error: Cannot find module '../controllers/note.controller.js'
This is because we haven’t defined the controller yet. Let’s do that now.

Writing the Controller functions

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 -

var Note = require('../models/note.model.js');

exports.create = function(req, res) {
   // Create and Save a new Note

};

exports.findAll = function(req, res) {
   // Retrieve and return all notes from the database.

};

exports.findOne = function(req, res) {
   // Find a single note with a noteId

};

exports.update = function(req, res) {
   // Update a note identified by the noteId in the request

};

exports.delete = function(req, res) {
   // Delete a note with the specified noteId in the request

};
Let’s now look at the implementation of the above controller functions one by one -

Creating a new Note

exports.create = function(req, res) {
   // Create and Save a new Note
   if(!req.body.content) {
       res.status(400).send({message: "Note can not be empty"});
   }
    var note = new Note({title: req.body.title || "Untitled Note", content: req.body.content});

   note.save(function(err, data) {
       console.log(data);
       if(err) {
           console.log(err);
           res.status(500).send({message: "Some error occurred while creating the Note."});
       } else {
           res.send(data);
       }
   });
};

Retrieving all Notes

exports.findAll = function(req, res) {
   // Retrieve and return all notes from the database.
   Note.find(function(err, notes){
       if(err) {
           res.status(500).send({message: "Some error occurred while retrieving notes."});
       } else {
           res.send(notes);
       }
   });
};

Retrieving a single Note

exports.findOne = function(req, res) {
   // Find a single note with a noteId
   Note.findById(req.params.noteId, function(err, data) {
       if(err) {
           res.status(500).send({message: "Could not retrieve note with id " + req.params.noteId});
       } else {
           res.send(data);
       }
   });
};

Updating a Note

exports.update = function(req, res) {
   // Update a note identified by the noteId in the request
   Note.findById(req.params.noteId, function(err, note) {
       if(err) {
           res.status(500).send({message: "Could not find a note with id " + req.params.noteId});
       }

       note.title = req.body.title;
       note.content = req.body.content;

       note.save(function(err, data){
           if(err) {
               res.status(500).send({message: "Could not update note with id " + req.params.noteId});
           } else {
               res.send(data);
           }
       });
   });
};

Deleting a Note

exports.delete = function(req, res) {
   // Delete a note with the specified noteId in the request
   Note.remove({_id: req.params.noteId}, function(err, data) {
       if(err) {
           res.status(500).send({message: "Could not delete note with id " + req.params.id});
       } else {
           res.send({message: "Note deleted successfully!"})
       }
   });
};

Testing our APIs

Creating a new Note using POST /notes API

Node Express Rest API Create a Note

Retrieving all Notes using GET /notes API

Node Express Rest API Retrieve All Notes

Retrieving a single Note using GET /notes/:noteId API

Node Express Rest API Retrieve a Single Note

Updating a Note using PUT /notes/:noteId API

Node Express Rest API Update a Note

Deleting a Note using DELETE /notes/:noteId API

Node Express Rest API Delete a Note