🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
HTML MASTER CLASS /// LEARN TAGS /// BUILD STRUCTURE /// SEMANTIC WEB /// HTML MASTER CLASS /// LEARN TAGS ///
Total XP: 0|💻 mernblog XP: 0

Completing CRUD

Complete your CRUD API. Understand how to use Mongoose's findByIdAndUpdate and findByIdAndDelete methods, why the { new: true } flag is critical, and the architectural theory behind securing endpoints to specific document owners.

LOADING ENGINE...

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

Select an unlocked node to view details root

Let's cut the fluff. Here is exactly what you need to know about this concept to survive in a real production environment.

1Completing CRUD

Look, if you've ever dealt with this in production, you know exactly what the problem is. We have successfully implemented the 'Create' and 'Read' operations. To complete our blog's backend functionality, we must implement 'Update' and 'Delete'. However, unlike reading a public blog post, updating or deleting data is a destructive action. We must strictly control who is allowed to perform these actions. If anyone can send a DELETE /api/posts/:id request and wipe out another user's content, our application is fundamentally insecure. This isn't just academic theory—understanding the *why* behind this is what separates junior devs from senior engineers. When you deploy a full-stack JavaScript app, this is the mechanic that prevents catastrophic failure.

+
/* The Security Requirement */
GET  /api/posts       -> Public (Anyone can read)
POST /api/posts       -> Protected (Must be logged in)
PUT  /api/posts/:id   -> Protected (Must be AUTHOR)
DEL  /api/posts/:id   -> Protected (Must be AUTHOR)
localhost:3000
localhost:3000 (MERN App)
[Completing CRUD] Output:

Component rendered successfully.
API data fetched via Express.

2The Update Endpoint

Look, if you've ever dealt with this in production, you know exactly what the problem is. To update a document, we use a PUT or PATCH HTTP request. In Mongoose, we use findByIdAndUpdate(). This method takes three arguments: the ID of the document to find, an object containing the new data to apply, and an options object. A critical option to include is { new: true }. By default, Mongoose returns the old, outdated document *before* the update was applied. Setting new: true forces Mongoose to return the freshly updated document back to the React client. This isn't just academic theory—understanding the *why* behind this is what separates junior devs from senior engineers. When you deploy a full-stack JavaScript app, this is the mechanic that prevents catastrophic failure.

+
router.put('/:id', async (req, res) => {
  try {
    // 1. ID to find, 2. Data to update, 3. Options
    const updatedPost = await Post.findByIdAndUpdate(
      req.params.id,
      req.body,
      { new: true }
    );
    res.status(200).json(updatedPost);
  } catch (err) {
    res.status(500).json(err);
  }
});
localhost:3000
localhost:3000 (MERN App)
[The Update Endpoint] Output:

Component rendered successfully.
API data fetched via Express.

3The Delete Endpoint

Look, if you've ever dealt with this in production, you know exactly what the problem is. Deleting a document is relatively straightforward using Mongoose's findByIdAndDelete(). When a DELETE request hits /api/posts/:id, Express extracts the id from the URL parameters and passes it to Mongoose. If the document is found and deleted, Mongoose returns the deleted document. If the document does not exist (perhaps it was already deleted), it returns null. We must check for this null state and return a 404 Not Found to the client if necessary. This isn't just academic theory—understanding the *why* behind this is what separates junior devs from senior engineers. When you deploy a full-stack JavaScript app, this is the mechanic that prevents catastrophic failure.

+
router.delete('/:id', async (req, res) => {
  try {
    const post = await Post.findByIdAndDelete(req.params.id);
    if (!post) {
      return res.status(404).json("Post not found");
    }
    res.status(200).json("Post deleted successfully");
  } catch (err) {
    res.status(500).json(err);
  }
});
localhost:3000
localhost:3000 (MERN App)
[The Delete Endpoint] Output:

Component rendered successfully.
API data fetched via Express.

4Enforcing Authorization

Look, if you've ever dealt with this in production, you know exactly what the problem is. Currently, our endpoints are fully functional, but dangerously exposed. Anyone with Postman can send a DELETE request to /api/posts/123 and destroy the database. To fix this, we must enforce Authorization at the route level. Before we call findByIdAndUpdate, we must first check if post.author.toString() === req.user.id. We will build out this req.user functionality in the upcoming Authentication module using JSON Web Tokens (JWT). This isn't just academic theory—understanding the *why* behind this is what separates junior devs from senior engineers. When you deploy a full-stack JavaScript app, this is the mechanic that prevents catastrophic failure.

+
router.delete('/:id', async (req, res) => {
  const post = await Post.findById(req.params.id);
  
  // SECURITY CHECK: Is the person making the request
  // the actual author of the post?
  if (post.author.toString() !== req.user.id) {
    return res.status(401).json("Not authorized");
  }
  
  await post.deleteOne();
});
localhost:3000
localhost:3000 (MERN App)
[Enforcing Authorization] Output:

Component rendered successfully.
API data fetched via Express.

5The Stage is Set

Look, if you've ever dealt with this in production, you know exactly what the problem is. We have now explored the theoretical architecture for secure CRUD operations. However, to actually implement these security guards, we need a robust identity system. How does the server know who req.user is? Since HTTP is completely stateless, the server forgets who you are the millisecond the request finishes. In the next module, we will solve this fundamental problem using JSON Web Tokens (JWT) and secure authentication. This isn't just academic theory—understanding the *why* behind this is what separates junior devs from senior engineers. When you deploy a full-stack JavaScript app, this is the mechanic that prevents catastrophic failure.

+
/* Security Required */
.curriculum { next: 'jwt_authentication'; }
localhost:3000
localhost:3000 (MERN App)
[The Stage is Set] Output:

Component rendered successfully.
API data fetched via Express.

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Continue Learning

Go Deeper

Related Courses