Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions existingMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const express = require("express");
const app = express();

// Use built-in JSON middleware
app.use(express.json()); // Read the request body, parses it as JSON, automatically sets req.body, rejects invalid JSON with 400

/**
* Middleware 1:
* Read X-Username header and attach it to req.username
*/
const usernameMiddleware = (req, res, next) => {
const username = req.header("X-Username");
req.username = username ? username : null;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code works, but it would probably be more normal to see either

req.username = username ?? null;

or

req.username = username || null;

A useful exercise is to understand the difference between the two and why the first one is better

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the defferent
Fisrt one is better option because:
Safer, more explicit, less error-prone, modern JavaScript best practice

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It depends whether 0 and/or an empty string are valid usernames as well!

next();
};

/**
* Middleware 2 (validation only):
* Ensure body is an array of strings
*/

// We still need to validate the shape of the data
const validateStringArrayBody = (req, res, next) => {
if (!Array.isArray(req.body)) {
return res.status(400).send("Request body must be a JSON array");
}

if (!req.body.every(item => typeof item === "string")) {
return res.status(400).send("Array must contain only strings");
}

next();

};

/**
* POST endpoint
*/



app.post(
"/",
usernameMiddleware,
validateStringArrayBody,
(req, res) => {
const username = req.username ?? "Anonymous";
const subjects = req.body;

res.send(
`You are authenticated as ${username}.

You have requested information about ${subjects.length} subjects: ${subjects.join(", ")}.`
);
}
);

app.listen(3000, () => {
console.log("Server running on port 3000");
});
71 changes: 71 additions & 0 deletions middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const express = require("express");
const app = express();

/**
* Middleware 1:
* Read X-Username header and attach it to req.username
*/
const usernameMiddleware = (req, res, next) => {
const username = req.header("X-Username");
req.username = username ? username : null;
next();
};


/**
* Middleware 2:
* Parse POST body as JSON array of strings
*/
const jsonArrayMiddleware = (req, res, next) => {
let rawBody = "";

req.on("data", chunk => {
rawBody += chunk;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good use of the req.on model, although other trainees just went for app.use(express.text()) !

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see this option

  • Express middleware parses the request body automatically
  • Converts the body into a string and stores it in req.body
  • Less code, easier to use for trainees

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do have to be careful though - unless you use text with type="application/json" it will just ignore the body!

});

req.on("end", () => {
let parsed;

try {
parsed = JSON.parse(rawBody);
} catch {
return res.status(400).send("Request body must be valid JSON");
}

if (!Array.isArray(parsed)) {
return res.status(400).send("Request body must be a JSON array");
}

if (!parsed.every(item => typeof item === "string")) {
return res.status(400).send("Array must contain only strings");
}

req.body = parsed;
next();
});
};



/**
* POST endpoint
*/
app.post(
"/",
usernameMiddleware,
jsonArrayMiddleware,
(req, res) => {
const username = req.username ?? "Anonymous";
const subjects = req.body;

res.send(
`You are authenticated as ${username}.

You have requested information about ${subjects.length} subjects: ${subjects.join(", ")}.`
);
}
);

app.listen(3000, () => {
console.log("Server running on port 3000");
});