Express JS - Learn what Matters. <Notes>
Tags: webdev, javascript, node, beginners
Published: 2023-11-29 05:14:38


documentation available at [Express website](https://expressjs.com/)

> npm i express --save

Once the Express is installed, let us see a simple Hello World! code with Express

```js
const path = require("path");
//Importing express
const express = require("express");

//we dfine a port so that we not only have development address but also on which port is it on
const PORT = process.env.PORT || 3500;


const app = express();
app.get("/", (req, res) => {
  res.send("Hello World");
});

  
app.listen(PORT, () => console.log(`Server is running on PORT: ${PORT}`));
```

*This should now show hello world when visiting to http://localhost:3500/

#### Let us see how to serve an Index.html file using express

```js
const path = require("path");
//Importing express
const express = require("express");
//we dfine a port so that we not only have development address but also on which port is it on
const PORT = process.env.PORT || 3500;
const app = express();


//1. Getting the index.html - With Regex ^(starts with) $(ends at) |(or) (html)?(This is optional contion making html optional)
app.get("^/$|/index(.html)?", (req, res) => {
  //This is first way, here we explicitly provide root with directory name in which it looks for views folder and index.html
  // res.sendFile('./views/index.html', {root: __dirname})
  
  // Another easier way is
  res.sendFile(path.join(__dirname, "views", "index.html"));

});

//2. let us serve another page to another route
app.get("/new-page(.html)?", (req, res) => {
//we have a folder name views in our directory, so we join views with new-page.html
  res.sendFile(path.join(__dirname, "views", "new-page.html"));
});

//3. Let us see how redirecting works ?
app.get("/old-page(.html)?", (req, res) => {
  res.redirect(301, "/new-page"); //301 is we are manually setting to 301 redirect i.e, permanent redirect
  //because by default it sets to 302 redirect code.
});

//4. Setting up a default route, i.e, /all or /*
app.get("/*", (req, res) => {
  res.status(404).sendFile(path.join(__dirname, "views", "404.html"));
});

  
app.listen(PORT, () => console.log(`Server is running on PORT: ${PORT}`));
```

1. Notice that the Express sets the status code automatically, if the page was found the status code is 200 automatically. Also notice that the Express can handle the regex expression, There we have mention that all routes that starts and ends with / and then we could easily keep .html as optional. This makes things easier
2. Note that Express follows like waterfall technique, i.e, it first looks for / or /index or /index.html then it moves down and found /new-page or /new-page.html . Means it doesn't just  stop at / it goes beyond it.
3. The redirecting is also easier with `res.redirect()` but to note here by default the status code is 302 by Express which means temporary moved to different location. We might have to redirect to a page that has been permanently relocated, in that case we can set the status code manually by passing it as the first parameter and then the redirected parameter.
4. We can add a 404 page not found manually by making a default route or `/*` means all routes to load a manual 404 error page. But in this case the status code will be 200 by default since the Express has essentially found the page that we are looking for. So we have to manually adjust that by doing `res.status(404).sendFile()` this will then simply fix the issues.

## Route Handlers

Now there is a  concept of route handlers and chaining of the route handlers. Let us see them in short. Note these develop a basic understanding of a concept middleware's in Express
example code
```js
app.get("/chain(.html)?",(req, res, next) => {
    console.log("Attempt to render the chain");
    next();
  },
  (req, res) => {
    res.send("Chain Rendered");
  }
);
```

So as in this code, there is a keyword `next` and then at the end of the code block of `app.get` we are calling `next()` this allows to run the next function that chained with this one. so in this case the output is, at first in the terminal it prints `Attempt to render the chain` and then it sends the small text `chain Rendered` in the browser on visiting the link http://localhost:3500/chain

There is one another method, i.e. we can make several functions like this and then chain them by passing them in the array, here is an example

```js
const one = (req, res, next) => {
  console.log("One executed");
  next();
};

const two = (req, res, next) => {
  console.log("Two executed");
  next();
};

const three = (req, res, next) => {
  console.log("Three executed");
  next();
};

const finish = (req, res) => {
  res.send("Render Finished");
};

app.get("/chain(.html)?", [one, two, three, finish]);
```

Output will be shown as 
```output
Server is running on PORT: 3500
One executed
Two executed
Three executed
```
and on visiting the link http://localhost:3500/chain it renders the page with the text Render Finished

So this is how the chaining works in Express. 
Now this will brings up something call the [[Middleware's]] 




### Steps to write the Express server

1. NPM install the dependencies - 
	`nodemon`
	`cors`
	`express`

2. configure the `package.json` in the `script` add the `dev : 'nodemon server'`  this is for starting the server file after `npm run dev` and every time server.js is saved the server will restart
3. create the file folder structure [[Node Folder Structure.canvas|Node Folder Structure]]
4. Import all modules in server.js (express, path, cors, )
5. create a port and create the app from express 
6. listen to the port and log the console
7. add middleware's using `app.use` 
	- `app.use(cors())`
	- Remember to use `cors` it is better to make the whitelist, then create an object lets say `corsOptions` this object has two keys, `origin :` and  `OptionsSucessStatus` , in the origin it is a function with a callback and origin arguments, and check if the origin is in the index of the whitelist. if the index of origin returns -1 then it is not in the whitelist therefore it returns the `callback(new Error("message")) `otherwise it returns `callback(null,true)`
```javascript
const whiteList = [
  "http://www.site.com",
  "http://127.0.0.1:3500",
  "http://localhost:3000",
];


const corsOptions = {
  origin: (origin, callback) => {
    if (whiteList.indexOf(origin) !== -1 || !origin) { // ||!origin is only for dev
      callback(null, true);
    } else {
      callback(new Error("Not Allowed by CORS!!"));
    }
  },
  OptionsSuceessStatus: 200,
};

module.exports = corsOptions;
```
- `app.use(express.urlencoded({extended : false}))`
- `app.use(express.json())`
- `app.use(express.static(path.join(__dirname, '/public'))` this is for root files in views
- `app.use('/subdir', express.static(path.join(__dirname,'/public'))` this is for the sub routes in this example it is subdir.
8. Add routes using `app.use('/', require("./routes/root)"`
9. Add sub-routes if there are any
10. Add `app.all('*', (req,res)){}` in this case add the status of 404 and also add the conditions of `req.accepts('html')` or `req.accpets('json')` to send the relevant 404 error page by `res.sendFile(path.join(__dirname, "views",'404.html'))` or the JSON as `res.json({err : '404 not found'})` else send the text by `res.type('text').send('404 not found!)'`
11. Inside the routes, import the express and path module, then make the router from `express.Router()` and then use the `router.get('/index.(html)?', patth)` and at last do `module.exports = router`
```javascript
const express = require("express");
const path = require("path");
const router = express.Router();
router.get("^/$|/index(.html)?", (req, res) => {
  res.sendFile(path.join(__dirname, "..", "views", "index.html"));
});

router.get("^/about(.html)?", (req, res) => {
  res.sendFile(path.join(__dirname, "..", "views", "about.html"));
});

module.exports = router;
```


#### Steps to write the API

1. Basic Steps :
	- Create a separate folder `api` inside the folder `routes` and make the JavaScript file
	- Inside it import the express and path, then create the router from `express.Router()`.
	- use `router.route('/').get('path', (req,res){}).put().delete().post()`
	- export the router using `module.exports = router`
2. More Advance Steps :
	- First create the controllers folder, inside the controllers folder we keep all the functional logic of CRUD operations and exports them in form of `modules.exports`
	- Now inside the routes, make the specific api routes for authentication or register and inside them use the `router = express()` and use `router.route("/").get(function from controller)`
	- Export the router and then edit the server.js file to add the api route on call.


I hope this would help you refresh your knowledge in using the Express framework in NodeJS.

The above information is compiled from :
References of all the source of information from my learning notes from YT creator and his 7 hour series of learning [NodeJS](https://www.youtube.com/watch?v=f2EqECiTBL8)
Author : [Dave Gray](https://www.youtube.com/@DaveGrayTeachesCode)