Skip to content

Conversation

@fikretellek
Copy link

@fikretellek fikretellek commented Apr 28, 2024

Learners, PR Template

Self checklist

  • I have committed my files one by one, on purpose, and for a reason
  • I have titled my PR with COHORT_NAME | FIRST_NAME LAST_NAME | REPO_NAME | WEEK
  • I have tested my changes
  • My changes follow the style guide
  • My changes meet the requirements of this task

Changelist

Briefly explain your PR.

Questions

Ask any questions you have for your reviewer.

@fikretellek
Copy link
Author

server is live on ---> https://module-servers.onrender.com/

"main": "server.js",
"scripts": {
"start": "node server.js"
"start": "nodemon server.js"

Choose a reason for hiding this comment

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

Nice touch using nodemon! This can save you a lot of time and effort during development. Well done!

typeof newMessage.text != "string" ||
typeof newMessage.from != "string"
) {
res.sendStatus(400).send("wrong input");

Choose a reason for hiding this comment

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

One suggestion for improvement is that instead of using res.sendStatus(400).send("wrong input"), you can use res.status(400).send("wrong input"). res.status(400) set the status code and then send the error message using send.

Copy link
Author

Choose a reason for hiding this comment

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

Ahh I see, that makes more sense. Thank you.

newMessage.text === "" ||
typeof newMessage.text != "string" ||
typeof newMessage.from != "string"
) {

Choose a reason for hiding this comment

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

If you want to go one further step, you can create your validation fun and give single responsibility to it. It looks like this:

function validateMessage(newMessage) {
     //your validation returns boolean
 }

app.post("/messages", (req, res) => {
  const newMessage = req.body;

  const isMessageValid = validateMessage(newMessage

  if (!isMessageValid)) {
    res.status(400).send("wrong input");
    return;
  }
// Rest of your code...

Copy link
Author

Choose a reason for hiding this comment

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

I have modified the route function. Could you have a look please?

res.json(messages);
});

app.get("/messages/id/:id", (req, res) => {

Choose a reason for hiding this comment

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

There is no right and wrong, but you generally don't need to include the word 'id' in the route path. you can simply use /messages/:id. It makes the endpoint more concise and follows a common convention in RESTful APIs.

Copy link
Author

Choose a reason for hiding this comment

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

I really had a bad time fixing this 😆 when I tried to create another route (ex: /message/search) it was getting recognised as :id parameter. I couldn't solve the problem and found this solution. After seeing this message spent an hour but still couldn't solve 😆

res.json(searchedMessage);
});

app.delete("/messages/id/:id", (req, res) => {

Choose a reason for hiding this comment

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

Same as before!

Copy link
Author

Choose a reason for hiding this comment

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

Can we set up a meeting for this issue? I couldn't find how to resolve dynamic and static path blocking

});

app.get("/messages/latest", (req, res) => {
const latestMessages = messages.slice(-10);

Choose a reason for hiding this comment

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

I'm sure you can to this more dynamic instead of using hardcoded length 💯

Copy link
Author

Choose a reason for hiding this comment

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

yes it makes more sense. I have updated the route with /messages/latest/:length route

Copy link

@musayuksel musayuksel left a comment

Choose a reason for hiding this comment

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

Hey @fikretellek ,

This is fantastic! Moving the validation logic to a separate function has already made the code significantly more readable and easier to test.

Here's an additional step you can explore to further improve the structure and maintainability of the code: it's called middleware. Don't worry, it's not your responsibility at this point, but I can see your potential and I'd love to introduce you to it for when you have some extra time to learn.

Middleware in Express allows you to create reusable functions that intercept incoming requests and perform actions before they reach the route handler. This is a great way to for common tasks like validation, authentication.

Here's an example of how you could implement message validation as middleware:

const messageValidationMiddleware = (req, res, next) => {
  const message = req.body;
  const isMessageValid = validateMessage(message);
  if (isMessageValid) {
    next(); // Pass it to the next middleware or route handler in your scenario
  } else {
    const errorMessage = new Error('Your message input is invalid :( ');
    next(errorMessage); // Pass the error to the global error handler
   // IT WILL SKIP ALL OTHER MIDDLEWARES AND ROUTES
  } 
};

// Now, in your route handler, you can remove the validation logic:

app.post('/messages', messageValidationMiddleware, (req, res) => {
  const newMessage = req.body;
  // Since the message has already been validated, we can safely assign an ID
  newMessage['id'] = messages[messages.length - 1].id + 1;
  // ... rest of your code
});

// ... OTHER ROUTES

const globalErrHandler = (err, req, res, next) => {
  res.status(400).send(err.message); // comes from any middleware,
// in this code it is `Your message input is invalid :(`
  // The status code can be dynamic in real applications, but that is beyond the scope of this explanation
};

app.use(globalErrHandler);

app.listen(process.env.PORT, () => {
  console.log(`listening on PORT ${process.env.PORT}...`);
});
  • The globalErrHandler function takes four arguments: err, req, res, and next.
  • When we can call next(err) in one of our middleware function, it will skip any remaining middleware and route handlers and jump straight to the globalErrHandler middleware.
  • The globalErrHandler receives the error object as the first argument (Error).
  • By utilising the globalErrHandler, we ensure std error handling throughout our app.

Remember, this is just an optional step you can explore for further learning. The current implementation is already great! Keep up the excellent work, @fikretellek .

@sonarqubecloud
Copy link

sonarqubecloud bot commented May 9, 2024

Quality Gate Passed Quality Gate passed

Issues
1 New issue
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarCloud

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants