├── .gitignore ├── public ├── text │ └── data.txt ├── img │ └── img1.jpg └── css │ └── style.css ├── model └── employees.json ├── middleware ├── errorHandler.js └── logEvents.js ├── views ├── subdir │ ├── test.html │ └── index.html ├── 404.html ├── index.html └── new-page.html ├── routes ├── subdir.js ├── root.js └── api │ └── employees.js ├── package.json ├── README.md ├── server.js └── logs └── reqLog.txt /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /public/text/data.txt: -------------------------------------------------------------------------------- 1 | Just some random text. -------------------------------------------------------------------------------- /public/img/img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitdagray/express_routers/HEAD/public/img/img1.jpg -------------------------------------------------------------------------------- /model/employees.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "firstname": "Dave", 5 | "lastname": "Gray" 6 | }, 7 | { 8 | "id": 2, 9 | "firstname": "John", 10 | "lastname": "Smith" 11 | } 12 | ] -------------------------------------------------------------------------------- /public/css/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-size: 36px; 9 | min-height: 100vh; 10 | color: #fff; 11 | background-color: #000; 12 | display: grid; 13 | place-content: center; 14 | } 15 | -------------------------------------------------------------------------------- /middleware/errorHandler.js: -------------------------------------------------------------------------------- 1 | const { logEvents } = require('./logEvents'); 2 | 3 | const errorHandler = (err, req, res, next) => { 4 | logEvents(`${err.name}: ${err.message}`, 'errLog.txt'); 5 | console.error(err.stack) 6 | res.status(500).send(err.message); 7 | } 8 | 9 | module.exports = errorHandler; -------------------------------------------------------------------------------- /views/subdir/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "08tut",
3 | "version": "1.0.0",
4 | "description": "Express tutorial",
5 | "main": "server.js",
6 | "scripts": {
7 | "start": "node server",
8 | "dev": "nodemon server"
9 | },
10 | "author": "Dave Gray",
11 | "license": "ISC",
12 | "dependencies": {
13 | "cors": "^2.8.5",
14 | "date-fns": "^2.23.0",
15 | "express": "^4.17.1",
16 | "uuid": "^8.3.2"
17 | },
18 | "devDependencies": {
19 | "nodemon": "^2.0.12"
20 | }
21 | }
--------------------------------------------------------------------------------
/routes/root.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const path = require('path');
4 |
5 | router.get('^/$|/index(.html)?', (req, res) => {
6 | res.sendFile(path.join(__dirname, '..', 'views', 'index.html'));
7 | });
8 |
9 | router.get('/new-page(.html)?', (req, res) => {
10 | res.sendFile(path.join(__dirname, '..', 'views', 'new-page.html'));
11 | });
12 |
13 | router.get('/old-page(.html)?', (req, res) => {
14 | res.redirect(301, '/new-page.html'); //302 by default
15 | });
16 |
17 | module.exports = router;
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # "Express JS Tutorial - Routers"
2 |
3 | ✅ [Check out my YouTube Channel with all of my tutorials](https://www.youtube.com/DaveGrayTeachesCode).
4 |
5 | **Description:**
6 |
7 | This repository shares the code applied during the Youtube tutorial. The tutorial is part of a [Node.js & Express for Beginners Playlist](https://www.youtube.com/playlist?list=PL0Zuz27SZ-6PFkIxaJ6Xx_X46avTM1aYw) on my channel.
8 |
9 | [YouTube Tutorial](https://youtu.be/Zh7psmf1KAA) for this repository.
10 |
11 | I suggest completing my [8 hour JavaScript course tutorial video](https://youtu.be/EfAl9bwzVZk) if you are new to Javascript.
12 |
13 | ### Academic Honesty
14 |
15 | **DO NOT COPY FOR AN ASSIGNMENT** - Avoid plagiargism and adhere to the spirit of this [Academic Honesty Policy](https://www.freecodecamp.org/news/academic-honesty-policy/).
16 |
--------------------------------------------------------------------------------
/routes/api/employees.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const data = {};
4 | data.employees = require('../../data/employees.json');
5 |
6 | router.route('/')
7 | .get((req, res) => {
8 | res.json(data.employees);
9 | })
10 | .post((req, res) => {
11 | res.json({
12 | "firstname": req.body.firstname,
13 | "lastname": req.body.lastname
14 | });
15 | })
16 | .put((req, res) => {
17 | res.json({
18 | "firstname": req.body.firstname,
19 | "lastname": req.body.lastname
20 | });
21 | })
22 | .delete((req, res) => {
23 | res.json({ "id": req.body.id })
24 | });
25 |
26 | router.route('/:id')
27 | .get((req, res) => {
28 | res.json({ "id": req.params.id });
29 | });
30 |
31 | module.exports = router;
--------------------------------------------------------------------------------
/middleware/logEvents.js:
--------------------------------------------------------------------------------
1 | const { format } = require('date-fns');
2 | const { v4: uuid } = require('uuid');
3 |
4 | const fs = require('fs');
5 | const fsPromises = require('fs').promises;
6 | const path = require('path');
7 |
8 | const logEvents = async (message, logName) => {
9 | const dateTime = `${format(new Date(), 'yyyyMMdd\tHH:mm:ss')}`;
10 | const logItem = `${dateTime}\t${uuid()}\t${message}\n`;
11 |
12 | try {
13 | if (!fs.existsSync(path.join(__dirname, '..', 'logs'))) {
14 | await fsPromises.mkdir(path.join(__dirname, '..', 'logs'));
15 | }
16 |
17 | await fsPromises.appendFile(path.join(__dirname, '..', 'logs', logName), logItem);
18 | } catch (err) {
19 | console.log(err);
20 | }
21 | }
22 |
23 | const logger = (req, res, next) => {
24 | logEvents(`${req.method}\t${req.headers.origin}\t${req.url}`, 'reqLog.txt');
25 | console.log(`${req.method} ${req.path}`);
26 | next();
27 | }
28 |
29 | module.exports = { logger, logEvents };
30 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const app = express();
3 | const path = require('path');
4 | const cors = require('cors');
5 | const { logger } = require('./middleware/logEvents');
6 | const errorHandler = require('./middleware/errorHandler');
7 | const PORT = process.env.PORT || 3500;
8 |
9 | // custom middleware logger
10 | app.use(logger);
11 |
12 | // Cross Origin Resource Sharing
13 | const whitelist = ['https://www.yoursite.com', 'http://127.0.0.1:5500', 'http://localhost:3500'];
14 | const corsOptions = {
15 | origin: (origin, callback) => {
16 | if (whitelist.indexOf(origin) !== -1 || !origin) {
17 | callback(null, true)
18 | } else {
19 | callback(new Error('Not allowed by CORS'));
20 | }
21 | },
22 | optionsSuccessStatus: 200
23 | }
24 | app.use(cors(corsOptions));
25 |
26 | // built-in middleware to handle urlencoded data
27 | // in other words, form data:
28 | // ‘content-type: application/x-www-form-urlencoded’
29 | app.use(express.urlencoded({ extended: false }));
30 |
31 | // built-in middleware for json
32 | app.use(express.json());
33 |
34 | //serve static files
35 | app.use('/', express.static(path.join(__dirname, '/public')));
36 | app.use('/subdir', express.static(path.join(__dirname, '/public')));
37 |
38 | // routes
39 | app.use('/', require('./routes/root'));
40 | app.use('/subdir', require('./routes/subdir'));
41 | app.use('/employees', require('./routes/api/employees'));
42 |
43 | app.all('*', (req, res) => {
44 | res.status(404);
45 | if (req.accepts('html')) {
46 | res.sendFile(path.join(__dirname, 'views', '404.html'));
47 | } else if (req.accepts('json')) {
48 | res.json({ "error": "404 Not Found" });
49 | } else {
50 | res.type('txt').send("404 Not Found");
51 | }
52 | });
53 |
54 | app.use(errorHandler);
55 |
56 | app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
--------------------------------------------------------------------------------
/logs/reqLog.txt:
--------------------------------------------------------------------------------
1 | 20210919 14:08:36 be8a4af7-d187-460c-b419-5063434bdf87 GET undefined /
2 | 20210919 14:08:36 6d664cd6-5d41-45f6-8e24-cbd841f3ff08 GET undefined /css/style.css
3 | 20210919 14:08:45 064bcc18-2a57-42c3-977b-968e1acdb2f6 GET undefined /subdir
4 | 20210919 14:09:07 33739abb-d102-4a90-b173-269f46702886 GET undefined /subdir/test.html
5 | 20210919 14:09:46 7f19e6e9-910d-446e-8280-cb6ab7a0633a GET undefined /subdir/dave
6 | 20210919 14:09:46 54feeaea-997a-4b83-b381-7171f770014a GET undefined /subdir/css/style.css
7 | 20210919 14:10:09 a6ca02b3-979d-41bb-b2b0-cbc503ae4179 GET undefined /dave
8 | 20210919 14:10:09 ace741a1-7342-4707-bdf6-4746c0883062 GET undefined /css/style.css
9 | 20210919 14:11:15 9a4eab31-d6e3-4fcf-b7b4-db3e602d4872 GET undefined /subdir/dave
10 | 20210919 14:11:15 6718115b-a4ff-4391-8949-4db5af99e6b6 GET undefined /subdir/css/style.css
11 | 20210919 14:11:25 c3588814-3774-4dd7-8c03-78a3e5264319 GET undefined /subdir/dave
12 | 20210919 14:11:25 39c460d2-7d5c-41c0-b4ae-dfcd1f92265b GET undefined /subdir/css/style.css
13 | 20210919 14:15:55 c77ac7af-89ed-4481-b688-77962b4af28d GET undefined /
14 | 20210919 14:15:55 d4209ed2-186c-4c5b-9899-334a1753fae3 GET undefined /css/style.css
15 | 20210919 14:16:01 97da2591-45a5-441b-9125-297477bc8cc3 GET undefined /new-page
16 | 20210919 14:16:01 d6297629-dc0f-42f5-8800-f4e4a0c3ac42 GET undefined /img/img1.jpg
17 | 20210919 14:16:01 155f0792-e597-4cbb-829d-4945e75469e4 GET undefined /css/style.css
18 | 20210919 14:16:17 81dfc877-f720-4bee-b398-f9f388967fd7 GET undefined /old-page
19 | 20210919 14:16:17 afa318e9-e722-4bdd-90d9-3b62700f909f GET undefined /new-page.html
20 | 20210919 14:16:17 fba8e0f9-5c06-44cd-b831-80b1666d72ac GET undefined /css/style.css
21 | 20210919 14:16:17 c78cb5ba-2f07-4d45-9506-6b31769a84c6 GET undefined /img/img1.jpg
22 | 20210919 14:16:23 00e0b3ca-3605-4217-b9a9-a44496014fda GET undefined /index
23 | 20210919 14:16:23 9d9ebeeb-8433-4304-97c1-caa300a49ee4 GET undefined /css/style.css
24 | 20210919 14:35:11 bbb68c55-e293-42a6-9c69-7ccee00a78a4 GET undefined /employees
25 | 20210919 14:35:51 782ddc31-f832-49b6-b594-cf9ef9d1a701 POST undefined /employees
26 | 20210919 14:36:33 c3689027-d6e0-44d5-ab49-a2da4deb3a64 PUT undefined /employees
27 | 20210919 14:36:53 86f56842-518f-44d2-b790-08a2d09d9727 DELETE undefined /employees
28 | 20210919 14:37:21 271bf802-e8f9-4ccd-ab4a-5e37b052bde1 GET undefined /employees/1
29 |
--------------------------------------------------------------------------------