why do we need router?
Router - it is a class, used to create modular, mountable route handlers.
Router instance is a middleware and routing system.
Every application has built in app router.
- create Router module
- create Router instance
const router = express.Router()
- define routes using router object
router.get('/',function(req,res){
res.send('Hello World')
})
- Export router
module.exports = router
- In app.js
- import router
const stu = require('./students.js)
- load router module
app.use('/',stu)
- app.use([path],[callback1, callback2..], callback)
- It mounts the specified middleware function at specified path.
- the middleware function is executed when the base of the requested path mathches path.
- a router is middleware
- an express app is middleware
- route parameter are URL segments used to capture values from URL.
- captured values are populated in req.params
- route parameter must be made up of 'word characer'([A-Za-z0-9])
- route parameter with RegX
- we can append it in parenthesses(())
/student/:id([0-9]{2})
- id should be between 0-9 and 2 digit
/student/:year/and/:month([a-z])
- month should be between a-z
Query string
/product//www.exam.com/product ? category=mobile
req.query = {"category":"mobile"}
/product //www.exam.com/product ? category=mobile&id=10
req.query = {"category" :"mobile", "id":10}
1) callback
app.get("/cb", (req, res) => {
res.send("get request");
});
2) more than one callback
app.get(
"/cb1",
(req, res, next) => {
console.log("First callback");
next(); //next is called to call second(next) callback then res will be sent
},
(req, res) => {
console.log(
"second callback will be called after first cb using next() method"
);
res.send("get request");
}
);
3) An array of callback
const cb1 = (req, res, next) => {
console.log("First call back");
next();
};
const cb2 = (req, res, next) => {
console.log("second call back");
next();
};
const cb3 = (req, res) => {
console.log("third call back");
res.send("An array of callback");
};
app.get("/arraycb", [cb1, cb2, cb3]);
4) combination of array and callback
app.get(
"/cbarr",
[cb1, cb2],
(req, res, next) => {
console.log("third callback");
next();
},
(req, res) => {
res.send("combination of callback");
}
);
5) chained route callbacks
--> when path is repeating for same APIs we can use chained route
app.route("/student")
.get((req, res) => {
res.send("all student");
})
.post((req, res) => {
res.send("create student");
})
.put((req, res) => {
res.send("update student");
});
app.route("/student")
.all((req, res, next) => {
console.log("this will be executed before all other");
next();
})
.get((req, res) => {
res.send("all student");
})
.post((req, res) => {
res.send("create student");
})
.put((req, res) => {
res.send("update student");
});
route parameter
app.get("/student/:id", (req, res) => {
console.log(req.params);
res.send("route parameter -req.params - {id:'11'}");
});
app.get("/student/:category/:id", (req, res) => {
console.log(req.params);
const { category, id } = req.params;
res.send(`route parameter ${req.params.category} ${req.params.id}`);
});
app.get("/student/:category/and/:old", (req, res) => {
console.log(req.params);
const { category, old } = req.params;
res.send(`route parameter ${req.params.category} ${req.params.old}`);
});
app.get("/train/:from-:to", (req, res) => {
console.log(req.params);
const { from, to } = req.params;
res.send(`route parameter ${req.params.from} ${req.params.to}`);
});
app.get("/train/:state.:city", (req, res) => {
console.log(req.params);
const { state, city } = req.params;
console.log("train gujrat.surat");
res.send(`route parameter ${req.params.state} ${req.params.city}`);
});
with regex
app.get("/student/:id([0-9]{2}", (req, res) => {
console.log(req.params);
console.log("train gujrat.surat");
res.send(`route parameter ${req.params.id}`);
});
app.param("id", (req, res, next, id) => {
console.log(req.params);
next();
});
app.get("/user/:id", (req, res, next) => {
console.log(req.params);
res.send(`${req.params.id}`);
});
app.param(["id", "page"], (req, res, next, value) => {
console.log(value);
next();
});
app.get("/user/:id/:page", (req, res, next) => {
console.log(req.params);
res.send(`${req.params.id}`);
});
query string
app.get("/user", (req, res, next) => {
/product www.exam.com/product?category=mobile&id=10
req.query = {"category":"mobile","id":10}
console.log(req.query);
res.send(`${req.params.id}`);
});
- sending html in response
const path = require("path");
const student = (req, res) => {
res.send("all student from controller got successfully");
};
const student = (req, res) => {
res.send("<h1>Home page</h1>");
console.log(path.join(process.cwd(), "views", "about.html"));
res.sendFile(path.join(process.cwd(), "views", "about.html"));
};
module.exports = student;
module.exports = {student, updateStu};
- static files in express
- to serve static files
- use express.static built-in middleware function
syntax:- express.static(root,[options])
example -
app.use(express.static('public'))
http://localhost:3000/css/style.css
2)
app.use('/static',express.static('public'))
http://localhost:3000/static/css/style.css
3) app.use('/static', express.static(path.join(process.cwd(), 'public')))
- Template engine
npm install ejs
In app.js
- setup directory where template files are located
app.set('views','./views')
- setup template engine to use
app.set('view engine','ejs')
- creating template files
- views/index.ejs
- views/about.ejs
- creating routes for template files
1) app.js
app.get('/',function(req,res){
res.render('index')
})
2) routes/web.js
router.get('/',function(req,res){
res.render('index')
})
- If view engine property is not set, we have to specify extention of view file
app.set('view engine','ejs') <-- if this is not set we have to give extention of file as below
router.get('/',function(req,res){
res.render('index.ejs')
})
- render method
res.render()
--> it renders a view and sends HTML string to the client.
syntax:-
res.render(view, [,locals],[,callback])
view
- the view argument is a string that is file path of the view file to render
locals - It's an object whose properties define local variable for the view
res.render('index',{name:'sonam'})
res.render('index',{name:'sonam'},function(err,html){
...
})
Middleware
- this are function which has access to request obj, response obj and next func
- next function executes next middleware
- middleware
- can execute any code
- make changes to req, res object
- end req,res cycle
- call next middleware in the stack
creating middleware
1) In app.js
app.use(function(req,res,next){
console.log('logged')
next()
})
2) In routes/student.js
router.use(function(req,res,next){
console.log('logged')
next()
})
3) middleware/logger.js
var myLogger = function(req,res,next){
console.log('logged')
next()
}
In app.js
const myLogger = require('./middleware/logger')
app.use(myLogger)
Using Middleware
- middleware executes first then next method of middleware calls another middleware then at last it will go to request and send response
1) Application level Middleware
- It is bound to instance of app
2) Router level Middleware
Router level middleware
- It is bound to an instance of express.Router()
Built-In middlware
- express.static - serves static assets
- express.json - parses incoming requests with json payloads
- express.urlencoded - parses incoming request with URL-encoded payloads
Third party middleware
- expressjs.com
Mongoose
- connect()
- Mongoose requires a connection to mongoDB database.
- we can connect localy hosted database with mongoose.connect()
syntax: connect(uri,options,callback)
uri - It is string used as connection uri
options - it's an object passed to the
mongodb driver's connect function
callback - it's callback func
example:-
mongoose.connect('mongodb://localhost:27017/schooldb')
mongoose.connect('mongodb://localhost:27017/schooldb',{
useNewUrlParser:true,
useUnifiedToplogy:true
})
Schema and Model in express
- A document schema is JSON object
- It allows to define shape and content of document in collection
- It is used to configure content of field and validate
example -
name:{type:String,required:true,trim:true}
age:{type:Number,required:true,min:18, max:50}
fees:{type:mongoose.Decimal128}
name:{type:Date,default:Date.now }
- everything in mongoose starts with Schema.
- Each schema map to a MongoDB collection - and defines shape of document within collection.
- bydefault, Mongoose adds an _id property to our schema.
syntax:
import mongoose from 'mongoose'
const nameSchema = new mongoose.Schema({
key1: String, // string is short hand for {type:String}
key2:Number,
key3:mongoose.Decimal128,
key4:[String],
key5:Boolean,
key6:[{key:String,key:Date}],
key7:Date
})
const studentSchema = new mongoose.Schema({
name:{type:String},
age:{type:Number},
fees:{type:mongoose.Decimal128},
hobbies:{type:Array},
isactive:{type:Boolean},
comments:[value:{type:String},publish:{type:Date}],
join:{type:Date},
})
_id property:- mongoose create _id of type ObjectId to our document.
ObjectIds encode local time at which they were created.
-we can also override mongoose default id with your own _id.
- mongoose will refuse to save document that has no _id.
const studentSchema = new mongoose.Schema({
name:{type:String,required:true},
age:{type:Number, min:18, max:65},
fees:{type:mongoose.Decimal128, validate: v => v>= 555},
hobbies:{type:Array},
isactive:{type:Boolean},
comments:[value:{type:String},publish:{type:Date}],
join:{type:Date, default:Date.now},
})
schema.path()
- It returns schema type of field(given path)
- studentSchema.path('age')
Model
- an instance of model is called document.
- model are used for creating document in database.
compiling schema
const studentSchema = mongoose.schema({})
const student = mongoose.model('Student',studentSchema)
- first argument is singular name of collection.
- mongoose automatically look for lowercase version of our model name and converts in plural.
- model Student is for students collection in database.
create document using Model
Defining Schema
- const studentSchema = mongoose.schema({name:String})
Compiling schema
- const Stu = mongoose.model('Student' ,stuSchema)
Creating Document
- const stu = new Student({name: 'sarita' })
Saving Document
await stu.save()
save()
- It is used to save document by inserting new document into the database if document.isNew is true.
- It returns undefined if used with callback or promise
- mongoose validates modified paths before saving. If field value is invalid it throws error.
const result = await stuDoc.save( {validateBeforeSave:false})
- Retrive document
find() - returns all
find(filter_obj,projection_obj,options_obj,callback)
example:-
await stuModel.find({name:'sonam'},{name:1,age:28},{skip:5})
Update document using mongoose
- findByIdAndUpdate()
- It finds a matching document and update as per arg,
syntax:-
findByIdAndUpdate(id,update,options,callback)
- id can be object, number or string
findByIdAndUpdate('65415788755',{name:"sa"},{returnDocument:after})
findByIdAndUpdate('65415788755',{$set:{name:"sa"}},{returnDocument:after})
updateOne()
- It is used to update single document. mongoDB will update only first document.
syntax:-
updateOne(filter,update,options,callback)
Example - updateOne({_id:"658415822",{name:"Sunil"},{upsert:true}})
upsert - If true, and no documents found, insert a new document
updateMany()
- It is used to update multiple document.
MongoDB will update all documents that match filter regardless of the value of the multi option.
Syntax:
updateMany(filter,update,options,callback)
Example:- updateMany({age:27},{name:"Sunil"},{upsert:true})
Delete Document
findByIdAndDelete():-
- It finds a matching document and delete it.
syntax:-
findByIdAndDelete(id,options,callback)
- id can be object, number or string
findByIdAndDelete('6859514455464654')
findByIdAndDelete({_id:'654649696464'})
deleteOne(condtions,options,callback)
deleteOne({_id:"65546464646'})
deleteMany()
- It is used to delete multiple document. MongoDB will delete all document that match condition.
syntax:
deleteMany(conditions,options,callback)
syntax: deleteMany({age:27})
syntax: deleteMany({name:'sonam',age:27})
Cookies
- A cookie is a small piece of text data set by web server on client's machine
- once it is set the client automatically returns cookie to web server with each request.
- this allows the server to place value it wishes to remember in cookies, have acces to them when creating response
cookie-parser
- cookie-parser is a middleware which parses cookie attached to the client req object.
- parse cookie header and populate req.cookies with an obj keyed by the cookie name
npm i cookie-parser
import cookieParser from 'cookie-parser'
var cookieParser = require(cookie-parser')
app.use(cookieParser())
res.cookie()
- It is used to set cookie name to value.
- The value parameter may be string or object converted to JSON.
syntax: res.cookie(name, value[,options])
res.cookie("username","geek")
res.cookie('cart',5)
res.cookie('cart',{items:[1,2,3]})
res.cookie('username','geek',{maxAge:5000}) // cookie will remain for 5 sec in clients machine
res.cookie('username','geek',{expires:new Date(Date.now() + 900000),httpOnly:true})
// cookie will remain for 5 sec in clients machine
res.cookie('username','geek',{path:'/admin'})
req.cookies
req.cookies - This property is used to get cookies.
when using cookie-parser middleware, this property is an object that contains cookies sent by the request.
- If the request contains no cookies, it defaults to {}
req.cookies
req.cookies.username
req.cookies.cart
res.clearCookie()
res.clearCookie()
- It is used to clear the cookies specified by name.
session in express
- cookies are stored in client while session are stored in server.
- cookies can contain less data while session can contain more data.
- cookies are insecure while session are secure.
express-session
-npm i express-session
var session = require('session')
app.use(session({secret:'indidsg', resave:false, saveUninitialized:true, cookie:{path:'/',httpOnly:true, secure:false, maxAge:5000}}))
