Skip to content

Commit 066dec6

Browse files
committed
advanced, bonus tp: add middleware recursivity
1 parent 4456c8d commit 066dec6

File tree

6 files changed

+132
-61
lines changed

6 files changed

+132
-61
lines changed

controllers/party.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
const Controller = require('../lib/controller');
2+
const Party = require('../models/party');
3+
4+
5+
module.exports = class PartyController extends Controller {
6+
static routes = [
7+
{ method: 'GET', url: '/party', action: 'index' },
8+
{ method: 'POST', url: '/party', action: 'create' },
9+
{ method: 'PUT', url: '/party/current', action: 'guess' },
10+
{ method: 'GET', url: '/party/current', action: 'history' },
11+
]
12+
13+
index() {
14+
return 'Create a party using POST'
15+
}
16+
17+
create() {
18+
Party.currentParty = new Party(
19+
this.req.body.min || 0,
20+
this.req.body.max || 100,
21+
);
22+
23+
this.res.statusCode = 204;
24+
}
25+
26+
guess() {
27+
if (!Party.currentParty) {
28+
throw new Error('No party');
29+
}
30+
31+
const result = Party.currentParty.guess(req.body);
32+
if (result === '=') {
33+
return `Félicitation, le chiffre était ${Party.currentParty.number}`;
34+
} else {
35+
return result; // + or -
36+
}
37+
}
38+
39+
history() {
40+
if (!Party.currentParty) {
41+
throw new Error('No party');
42+
}
43+
44+
return Party.currentParty.guesses.join(', ');
45+
}
46+
}

lib/controller.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
module.exports = class Controller {
2+
constructor(req, res) {
3+
this.req = req;
4+
this.res = res;
5+
}
6+
7+
callRoute(route) {
8+
// Execute the action of the route
9+
const result = this[route.action]();
10+
11+
// // =>
12+
// const handler = this[route.action];
13+
// // =>
14+
// const handler = this['create'];
15+
// // =>
16+
// const handler = this.create;
17+
// // =>
18+
// const result = handler();
19+
//
20+
if (this.res.statusCode) {
21+
this.res.statusCode = 200;
22+
}
23+
24+
this.res.write(result);
25+
this.res.end();
26+
}
27+
28+
static middleware(req, res, next) {
29+
for (const route of this.routes) {
30+
if (req.method === route.method && req.url === route.url) {
31+
const ctrl = new this(req, res)
32+
ctrl.callRoute(route);
33+
return;
34+
}
35+
}
36+
37+
next();
38+
}
39+
}

main.js

+14-61
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,22 @@
11
const http = require('http');
2-
const Party = require('./models/party');
32

4-
function bodyMiddleware(req, res, next) {
5-
if (['GET', 'HEAD', 'DELETE', 'OPTIONS'].includes(req.method)) {
6-
return next(req, res);
7-
}
3+
const PartyController = require('./controllers/party');
4+
const bodyMiddleware = require('./middlewares/body');
5+
const errorMiddleware = require('./middlewares/error');
6+
const notFoundMiddleware = require('./middlewares/notFound');
87

9-
let data = '';
10-
11-
req.on('data', (chunk) => data += chunk);
12-
req.on('end', () => {
13-
try {
14-
data = JSON.parse(data);
15-
} catch {
16-
res.statusCode = 400
17-
return res.end('JSON body is invalid');
18-
}
19-
20-
req.body = data;
21-
22-
next(req, res);
23-
})
24-
}
25-
26-
function errorMiddleware(req, res, next) {
27-
try {
28-
next(req, res);
29-
} catch (err) {
30-
res.statusCode = 500;
31-
res.end(err.message);
32-
}
33-
}
348

359
function handleRequest(req, res) {
36-
bodyMiddleware(req, res, (req, res) => errorMiddleware(req, res, handleRouting));
37-
}
38-
39-
function handleRouting(req, res) {
40-
if (req.method === 'POST' && req.url === '/party') {
41-
Party.currentParty = new Party(req.body.min || 0, req.body.max || 100);
42-
res.statusCode = 204;
43-
} else if (req.method === 'PUT' && req.url === '/party/current') {
44-
if (!Party.currentParty) {
45-
throw new Error('No party');
46-
}
47-
48-
const result = Party.currentParty.guess(req.body);
49-
if (result === '=') {
50-
res.write(`Félicitation, le chiffre était ${Party.currentParty.number}`);
51-
} else {
52-
res.write(result); // + or -
53-
}
54-
res.statusCode = 200;
55-
} else if (req.method === 'GET' && req.url === '/party/current') {
56-
if (!Party.currentParty) {
57-
throw new Error('No party');
58-
}
59-
60-
res.statusCode = 200;
61-
res.write(Party.currentParty.guesses.join(', '));
62-
} else {
63-
res.statusCode = 404;
64-
}
65-
66-
res.end();
10+
const middlewares = [
11+
bodyMiddleware,
12+
errorMiddleware,
13+
PartyController.middleware,
14+
notFoundMiddleware,
15+
]
16+
17+
// @todo apply middleware one after the other
18+
// remplacer la ligne suivante, par quelque chose de dynamique
19+
// bodyMiddleware(req, res, (req, res) => errorMiddleware(req, res, handleRouting));
6720
}
6821

6922

middlewares/body.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module.exports = function bodyMiddleware(req, res, next) {
2+
if (['GET', 'HEAD', 'DELETE', 'OPTIONS'].includes(req.method)) {
3+
return next(req, res);
4+
}
5+
6+
let data = '';
7+
8+
req.on('data', (chunk) => data += chunk);
9+
req.on('end', () => {
10+
try {
11+
data = JSON.parse(data);
12+
} catch {
13+
res.statusCode = 400
14+
return res.end('JSON body is invalid');
15+
}
16+
17+
req.body = data;
18+
19+
next(req, res);
20+
})
21+
}

middlewares/error.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = function errorMiddleware(req, res, next) {
2+
try {
3+
next(req, res);
4+
} catch (err) {
5+
res.statusCode = 500;
6+
res.end(err.message);
7+
}
8+
}

middlewares/notFound.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = function notFoundMiddleware(req, res) {
2+
res.statusCode = 404;
3+
res.end();
4+
}

0 commit comments

Comments
 (0)