Sunday, April 26, 2020

Routing in Express


Express is one of the popular web frameworks for Node.js. It provides a wrapper to very useful functionality such as Rendering, Routing etc. In this session, i am going to cover Router() in Express framework.
Express router is a class which helps us to create router handlers. By router handler i mean to not just providing routing to our app but also can extend this routing to handle validation, handle 404 or other errors etc.
To demonstrate the usage of Routing in Express i am going to cover the following points step by step. At the end you will have a complete code covering all scenarios.
1.     Basic routing
2.     Advance routing using middleware
3.     Middleware Router
4.     Accessing parameter in routing
5.     Handling 404 errors

Here is our Server file that covers all the above points.

1.   Basic Routing: For Basic routing Create a file with the code
server.js
var express = require('express');
var app = express();
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log('Server started at Port: %s'PORT);
});

// Root URL
app.get('/'function (reqres) {
  res.sendFile(__dirname + '/home.html');
});

// Basic Routing
app.get('/home', (reqres=> {
  res.sendFile(__dirname + '/home.html');
});
app.get('/about', (reqres=> {
  res.sendFile(__dirname + '/about.html');
});
app.get('/contact', (reqres=> {
  res.sendFile(__dirname + '/contact.html');
});

Also, create three HTML files at the same path with the code
home.html, about.html and contact.html

home.html (Add same code in other files replacing the naming convention)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Home</title>
    <style>
      .container {
        background-colorskyblue;
        height200px;
        border-radius5px;
        box-shadow2px 2px;
      }
    </style>
  </head>
  <body>
    <a href="/home">Home</a>
    <a href="/about">About</a>
    <a href="/contact">Contact</a>
    <div class="container">
      <h4 style="padding: 10px;">Home</h4>
    </div>
  </body>
</html>


2.   Advance Routing: For advance routing update file with the code
server.js
// Advance Routing using Router
const router = express.Router();
app.use('/admin'router);

router.get('/dashboard', (reqres=> {
  res.sendFile(__dirname + '/dashboard.html');
});
router.get('/development', (reqres=> {
  res.sendFile(__dirname + '/development.html');
});
router.get('/training', (reqres=> {
  res.sendFile(__dirname + '/training.html');
});


Also, create three more HTML files on the same path with the same above HTML code with the updated naming convention
dashbord.html, development.html and training.html


3.   Middleware RouterMiddleware – as the name implies will be executed before your routes get invoked. There are many possible usages for using Middleware for routes such as to log every request before its invoked or finding out whether request is proper or not.
Let’s define one simple Middleware which will print the type of Request ( GET, POST etc ).

server.js
// Router middleware, mentioned it before defining routes.
router.use(function (reqresnext) {
  console.log(req.method + ' ' + req.url);
  next();
});

next() function will take your router to next routes.


4.   Accessing parameter in Routing : Before explaining this scenario, let me show you how routes with params look like.

Route : http://localhost/admin/:name/
Route with data : http://localhost/admin/pankaj/
So name – > pankaj. Now we can access this params in Route as well as on Middleware. Let me show you both.

Case 1: Accessing it in Middleware.
Assuming the param name is “id”.
// This middle-ware will get the id param
// check if its 0 else go to next router.
router.use('/:id'function (reqresnext) {
  if (req.params.id == 0) {
    res.send('Message: You must pass ID other than 0');
  } else next();
});

Case 2: Accessing it in Router.
router.get('/:id'function (reqres) {
  res.send('Message: Hello ' + req.params.id);
});

Now we create a separate folder Router for structure your application better.
Here is complete code “admin.js”

const express = require('express');
const router = express.Router();

// Router middleware, mentioned it before defining routes.
router.use(function (reqresnext) {
  console.log(req.method + ' ' + req.url);
  next();
});

// This middle-ware will get the id param
// check if its 0 else go to next router.
router.use('/:id'function (reqresnext) {
  if (req.params.id == 0) {
    res.send('Message: You must pass ID other than 0');
    } else next();
});

// CASE-2 This middle-ware will get the id param 
// with valid admin name   
router.get('/:id'function (reqres) {
  res.send('Message: Hello ' + req.params.id);
});

router.get('/dashboard', (reqres=> {
  res.sendFile(__dirname + '/dashboard.html');
});
router.get('/development', (reqres=> {
  res.sendFile(__dirname + '/development.html');
});
router.get('/training', (reqres=> {
  res.sendFile(__dirname + '/training.html');
});

// Export your router
module.exports = router;

server.js
// Import Router from admin.js
const router = require('./Router/admin');
app.use('/admin'router);


5.   Handling 404 errors
server.js
// If any of the above URL not matched
// will call FALLBACK function for 404
app.use('*'function (reqres) {
  res.status(404).sendFile(__dirname + '/404.html');
});
Now Create 404.html in same folder and it will be accessed when unrecognized URL will be called.
404.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>404</title>
    <style>
      .status {
        align-itemscenter;
        text-aligncenter;
        font-size500%;
      }
    </style>
  </head>
  <body>
    <p class="status">404!</p>
  </body>
</html>



Tuesday, April 21, 2020

Express Middleware

Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. The next middleware function is commonly denoted by a variable named next.
  1. As name suggests it comes in middle of something and that is request and response cycle.
  2. Middleware has access to request and response object.
  3. Middleware has access to next function of request-response life cycle.


Middleware functions can perform the following tasks:
·       Execute any code.
·       Make changes to the request and the response objects.
·       End the request-response cycle.
·       Call the next middleware in the stack.
If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging.

What is this next()?

A middleware is basically a function that will the receive the Request and Response objects, just like your route Handlers do. As a third argument you have another function which you should call once your middleware code completed. This means you can wait for asynchronous database or network operations to finish before proceeding to the next step. This might look like the following:


If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging.

Types of express middleware

·       Application level middleware app.use
·       Router level middleware router.use
·       Built-in middleware express.static,express.json,express.urlencoded
·       Error handling middleware app.use(err,req,res,next)
·       Thirdparty middleware bodyparser,cookieparser

 

Example: Logging Middleware (Application Level Middleware )

const express = require('express');
const app = express();

// application level middleware
app.use((reqresnext=> {
  console.log(`Logged  ${req.url}  ${req.method} -- ${new Date()}`);
  next();
});

// users route
app.get('/users', (reqres=> {
  res.json({
    status: true,
  });
});

// save route
app.post('/save', (reqres=> {
  res.json({
    status: true,
  });
});

app.listen(3002, (reqres=> {
  console.log('server running on port 3002');
});

Output