-
-
Notifications
You must be signed in to change notification settings - Fork 26
LONDON | 25-SDC-Nov | Zohreh Kazemianpour | Sprint 3 | Middleware #66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| node_modules/ | ||
| .env |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| const express = require('express'); | ||
| const app = express(); | ||
| app.use(express.json()); | ||
|
|
||
| // Header Middleware | ||
| const checkUsername = (req, res, next) => { | ||
| const usernameHeader = req.get("X-Username"); | ||
| req.username = usernameHeader || null; | ||
| next(); | ||
| }; | ||
|
|
||
|
|
||
| // validates data | ||
| const validateSubjects = (req, res, next) => { | ||
|
|
||
| const subjects = req.body; | ||
|
|
||
| if ( | ||
| !Array.isArray(subjects) || | ||
| !subjects.every((item) => typeof item === "string") | ||
| ) { | ||
| return res.status(400).send("Invalid input: expected an array of strings."); | ||
| } | ||
| next(); | ||
| }; | ||
|
|
||
|
|
||
|
|
||
| // The Endpoint | ||
| app.post("/subjects", checkUsername, validateSubjects, (req, res) => { | ||
| const { username, body: subjects } = req; | ||
|
|
||
| // Handle Authentication Message | ||
| const authPart = username | ||
| ? `You are authenticated as ${username}.` | ||
| : "You are not authenticated."; | ||
|
|
||
| // Handle subject vs subjects | ||
| const count = subjects.length; | ||
| const subjectText = count === 1 ? "subject" : "subjects"; | ||
|
|
||
| // 3. Handle the list formatting | ||
| const listPart = count > 0 ? `: ${subjects.join(", ")}.` : "."; | ||
|
|
||
| res.send( | ||
| `${authPart}\n\nYou have requested information about ${count} ${subjectText}${listPart}`, | ||
| ); | ||
| }); | ||
|
|
||
|
|
||
|
|
||
| app.listen(3000, () => { | ||
| console.log('Server is running on port 3000'); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| const express = require('express'); | ||
| const app = express(); | ||
|
|
||
| // 1. Header Middleware | ||
| const checkUsername = (req, res, next) => { | ||
| const usernameHeader = req.get("X-Username"); | ||
| req.username = usernameHeader || null; | ||
| next(); | ||
| }; | ||
|
|
||
| // 2. Body Parser Middleware | ||
| const ensureJsonStringArray = (req, res, next) => { | ||
| let rawBody = ""; | ||
|
|
||
| req.on("data", (chunk) => { | ||
| rawBody += chunk; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a subtle bug here. chunk is bytes. When you do rawBody+=chunk it does a toString. However a single character in UTF8 can be up to 4 bytes. If your chunk ends in the middle of those 4 then the string conversion goes wrong. Better is to concatenate the byte chunks and convert once. |
||
| }); | ||
|
|
||
| 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(); | ||
| }); | ||
| }; | ||
|
|
||
|
|
||
|
|
||
| // 3. The Endpoint | ||
| app.post("/subjects", checkUsername, ensureJsonStringArray, (req, res) => { | ||
| const { username, body: subjects } = req; | ||
|
|
||
| // Handle Authentication Message | ||
| const authPart = username | ||
| ? `You are authenticated as ${username}.` | ||
| : "You are not authenticated."; | ||
|
|
||
| // Handle subject vs subjects | ||
| const count = subjects.length; | ||
| const subjectText = count === 1 ? "subject" : "subjects"; | ||
|
|
||
| // 3. Handle the list formatting | ||
| const listPart = count > 0 ? `: ${subjects.join(", ")}.` : "."; | ||
|
|
||
| res.send( | ||
| `${authPart}\n\nYou have requested information about ${count} ${subjectText}${listPart}`, | ||
| ); | ||
| }); | ||
|
|
||
|
|
||
|
|
||
| app.listen(3000, () => { | ||
| console.log('Server is running on port 3000'); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you deliberately using || instead of ?? here? Are you clear what the difference is? If yes to both, then no problem.