0

I've looked through a bunch of other SO posts and have found different ways to do this, so I'm wondering which is most preferred. I'm teaching this to students, so I want to give them best practices.

If I have the following BlogPost object (Simplified):

var BlogPostSchema = new mongoose.Schema({
    body: String,
    comments: [String]
});

and I want to add a new comment to the array of comments for this blog, I can think of at least 3 main ways to accomplish this:

1) Push the comment to the blog object in Angular and submit a PUT request to the /blogs/:blogID endpoint, updating the whole blog object with the new comment included.

2) Submit a POST request to a /blogs/:blogID/comments endpoint where the request body is just the new comment, find the blog, push the comment to the array in vanilla js, and save it:

BlogPost.findById(req.params.blogID, function(err, blogPost) {
    blogPost.comments.push(req.body);
    blogPost.save(function(err) {
        if (err) return res.status(500).send(err);
        res.send(blogPost);
    });
});

OR

3) Submit the POST to a /blogs/:blogID/comments endpoint with the request body of the new comment, then use MongoDB's $push or $addToSet to add the commend to the array of comments:

BlogPost.findByIdAndUpdate(
    req.params.blogID,
    {$push: {comments: req.body}},
    {safe: true, new: true},
    function(err, blogPost) {
        if (err) return res.status(500).send(err);
        res.send(blogPost);
    });
});

I did find this stackoverflow post where the answerer talks about option 2 vs. option 3 and basically says to use option 2 whenever you can, which does seem simpler to me. (And I usually try to avoid methods that stop me from being able to use hooks and other mongoose goodies.)

What do you think? Any advice?

1
  • I would go with option 3. Both 2 and 3 are basically the same. Option 3 does the findAndUpdate server side (resulting in 1 call to the server which returns the updated document). Where in option 2 you first retrieve the blogPost and then send the update to the server (the .save action) which are 2 calls to the server. Commented Nov 11, 2016 at 23:49

1 Answer 1

1

From application point of view, point 3 is better. The reason I think are.

  1. The query itself specifies what we are trying to achieve. it's easily readable.
  2. save function is a wild card, so we don't know what it's going to change.
  3. if you fetch the document and manipulate it and then call save it, there is outside but real chance that you might mess up some other field of the document in process of manipulation unintentionally, not the case with point 3.
  4. In case of addToSet,basically the previous point is more visible.
  5. Think about the concurrency, if multiple calls comes with different comment for same blog and you are trying option 2, there is a chance that you might override the changes which were done in between you fetched the document and when you are saving it. Option 3 is better in that sense.

Performance wise they both do the same thing, so there might not be much or any visible difference. But option 3 is bit safer and cleaner.

Sign up to request clarification or add additional context in comments.

1 Comment

I guess my only concern is if I need to use a pre- or post-save, etc. hook with mongoose, then the findByIdAndUpdate method won't let me do that. But maybe I write it this way for now, and then if I find a need for a pre- or post- hook of some kind I'll switch it over. Thanks for the thoughts!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.