West Midlands | 26 March SDC | Iswat Bello | Sprint 3 | Middleware exercises#93
West Midlands | 26 March SDC | Iswat Bello | Sprint 3 | Middleware exercises#93Iswanna wants to merge 10 commits into
Conversation
- Exclude node_modules/ and package-lock.json from version control - Ignore environment variables (.env) and system files (.DS_Store) - Exclude build artifacts (dist/, build/) and log files (*.log) - Ignore VS Code workspace settings (.vscode/) - Reduce repository size and prevent committing sensitive data
- Add username middleware that reads X-username header and sets req.username (or null). - Add array middleware that accumulates request bytes, parses JSON, validates it's an array of strings, assigns req.body or returns 400 on invalid input. - Add package.json with Express dependency.
Enable ES module syntax (import/export) for the project by setting "type": "module" in package.json.
…dd route and start server - Create Express app instance and use PORT from process.env with 3000 fallback. - Add try/catch around JSON.parse in array middleware and return 400 on invalid JSON. - Add POST "/" route that composes response using usernameMiddleware and arrayMiddleware. - Start server with app.listen.
- Rename middleware-exercise/app.js to middleware-exercise/two custom-written middlewares.js - Clarifies that the file contains two custom middleware implementations
- Change condition in two-custom-written-middlewares.js from MessageCount <= 1 to MessageCount === 1 so "subject" is used only when there is exactly one item (zero now uses "subjects").
- Add off-the-shelf-middleware.js: create Express app and listen on PORT (env fallback to 3000). - Add username middleware (reads X-username header into req.username). - Add validateArray middleware (ensures JSON body is an array of strings; returns 400 on invalid input). - Add POST "/" route that composes a response using the middlewares and starts the server.
- Add README.md describing how to run the custom and off-the-shelf middleware demos. - Document key concepts: middleware pattern, manual parsing vs express.json, env PORT fallback, and process management. - Include curl examples for valid and invalid requests and note default port 3000.
nedssoft
left a comment
There was a problem hiding this comment.
Really strong submission, Iswat — and thank you for the README especially. The "Key Concepts Learned" section and the curl examples made this a pleasure to review. 👏
A few things you've done really well:
- You validate that every item is a string, not just that the body is an array — lots of people stop at
Array.isArray, so well spotted. - In the custom parser you've wrapped
JSON.parsein atry/catch, so a malformed body returns a 400 instead of crashing the server. 👍 - You read
PORTfrom the environment with a sensible fallback.
I've left two questions to think about rather than fixes — nothing blocking the big picture. Have a look and let me know your thoughts!
| ) { | ||
| next(); | ||
| } else { | ||
| res.status(400).send("Error message"); |
There was a problem hiding this comment.
You wrote a really clear, helpful 400 message over in the custom version — "Invalid request body. Expected a JSON array containing only strings." Compare it with "Error message" here: which one helps the person calling your API understand what went wrong? Could this one tell them as much as the other does?
There was a problem hiding this comment.
The error message in the custom version is more descriptive because it explicitly tells the caller a JSON array of strings is required. This helps them identify exactly which part of their request was invalid, whereas 'Error message' leaves them guessing.
I have updated the error message accordingly.
There was a problem hiding this comment.
Perfect — and your explanation nails exactly why it matters: a descriptive error tells the caller what went wrong so they're not left guessing. 👍 It now matches your nice custom-version message. This is sorted — marking it Complete. (No need to chase the String.fromCharCode/Buffer question for this exercise — that was just an optional rabbit hole if it ever piques your curiosity.) Lovely work, Iswat.
|
|
||
| // When the whole message has arrived, we process it | ||
| req.on("end", () => { | ||
| const bodyString = String.fromCharCode(...bodyBytes); |
There was a problem hiding this comment.
Lovely manual parser! Since this exercise is all about handling raw bytes, try sending a value with an accent or an emoji — ["café"] or ["🐝"] — and see whether it comes back out intact.
Have a look at what String.fromCharCode does with the individual bytes of a multi-byte character, and whether Node gives you a tidier way to turn a set of byte chunks back into a string. (Something to investigate rather than copy: what could you do with the Buffer objects that data hands you?)
There was a problem hiding this comment.
String.fromCharCode will try to turn every single number into its own character. This distorted the output because special characters (like emojis or accents) are actually multi-byte, meaning they need 2 or 4 numbers to stay together to form one character. Buffer.concat keeps those numbers together so .toString() can read them correctly.
Kindly see two screenshots attached of when I used String.fromCharCode and Buffer.concat respectively
Thank you for the detailed feedback! I’m glad the README and the validation logic were clear. I’ve updated the code based on your questions. |
nedssoft
left a comment
There was a problem hiding this comment.
Brilliant! I'm glad you went further to explore this and can appreciate the difference.
Good job 👍
|
Thank you! It was really eye-opening to see how the bytes were being 'shattered' in the console when I used the spread operator. I definitely have a much better understanding now of why Buffers are so important for handling real-world data like emojis and accents! |
Learners, PR Template
Self checklist
Changelist
In this PR, I created two directories to demonstrate different approaches to Express middleware:
X-Usernameheader, and another (arrayMiddleware) manually handles raw data streams to parse and validate aJSONarray of strings.express.json()middleware. This version includes a streamlinedvalidateArraymiddleware to ensure the parsed body meets specific requirements.