Skip to content

West Midlands | 26 March SDC | Iswat Bello | Sprint 3 | Middleware exercises#93

Open
Iswanna wants to merge 10 commits into
CodeYourFuture:mainfrom
Iswanna:middleware-exercises
Open

West Midlands | 26 March SDC | Iswat Bello | Sprint 3 | Middleware exercises#93
Iswanna wants to merge 10 commits into
CodeYourFuture:mainfrom
Iswanna:middleware-exercises

Conversation

@Iswanna

@Iswanna Iswanna commented Jun 5, 2026

Copy link
Copy Markdown

Learners, PR Template

Self checklist

  • I have titled my PR with Region | Cohort | FirstName LastName | Sprint | Assignment Title
  • My changes meet the requirements of the task
  • I have tested my changes
  • My changes follow the style guide

Changelist

In this PR, I created two directories to demonstrate different approaches to Express middleware:

  • two-custom-written-middlewares.js: Features two custom-written middlewares. One extracts a username from the X-Username header, and another (arrayMiddleware) manually handles raw data streams to parse and validate a JSON array of strings.
  • off-the-shelf-middleware.js: Refactors the previous app to use the built-in express.json() middleware. This version includes a streamlined validateArray middleware to ensure the parsed body meets specific requirements.

Iswanna added 8 commits May 9, 2026 23:26
- 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.
@Iswanna Iswanna added 📅 Sprint 3 Assigned during Sprint 3 of this module Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. Module-Decomposition The name of the module. labels Jun 5, 2026
@nedssoft nedssoft added Review in progress This review is currently being reviewed. This label will be replaced by "Reviewed" soon. and removed Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. labels Jun 24, 2026

@nedssoft nedssoft left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.parse in a try/catch, so a malformed body returns a 400 instead of crashing the server. 👍
  • You read PORT from 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");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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?

@Iswanna Iswanna Jun 25, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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?)

@Iswanna Iswanna Jun 25, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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

Screenshot 2026-06-25 174612 Screenshot 2026-06-25 175030

@nedssoft nedssoft added Reviewed Volunteer to add when completing a review with trainee action still to take. and removed Review in progress This review is currently being reviewed. This label will be replaced by "Reviewed" soon. labels Jun 24, 2026
@nedssoft nedssoft added Complete Volunteer to add when work is complete and all review comments have been addressed. and removed Reviewed Volunteer to add when completing a review with trainee action still to take. labels Jun 25, 2026
@Iswanna

Iswanna commented Jun 25, 2026

Copy link
Copy Markdown
Author

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.parse in a try/catch, so a malformed body returns a 400 instead of crashing the server. 👍
  • You read PORT from 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!

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.
Thanks for the challenge; it really helped me understand how Node handles raw data.

@Iswanna Iswanna requested a review from nedssoft June 25, 2026 17:20

@nedssoft nedssoft left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Brilliant! I'm glad you went further to explore this and can appreciate the difference.

Good job 👍

@Iswanna

Iswanna commented Jun 25, 2026

Copy link
Copy Markdown
Author

Brilliant! I'm glad you went further to explore this and can appreciate the difference.

Good job 👍

@Iswanna Iswanna closed this Jun 25, 2026
@Iswanna Iswanna reopened this Jun 25, 2026
@Iswanna

Iswanna commented Jun 25, 2026

Copy link
Copy Markdown
Author

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Complete Volunteer to add when work is complete and all review comments have been addressed. Module-Decomposition The name of the module. 📅 Sprint 3 Assigned during Sprint 3 of this module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants