Skip to content

FEATURE: Refactor Save endpoint to use MongoDB $push instead of fetch-all-then-$set #31

Description

@DewaldOosthuizen

Summary

Save.post() in web/app.py (lines 149-158) retrieves the entire Messages array from MongoDB into Python memory, appends the new message locally, then writes the full array back with $set. This is an unnecessary round-trip and will degrade as the messages list grows. MongoDB's $push operator appends atomically in a single update command.

Background

The current pattern introduces a TOCTOU race: two concurrent saves for the same user can overwrite each other's messages. Using $push eliminates both the read round-trip and the race condition, which is the idiomatic MongoDB approach.

Affected Areas

  • web/app.pySave.post(), lines 149-158
  • get_user_messages() helper — still needed for Retrieve, but no longer called from Save

Recommended Fix

class Save(Resource):
    @requires_auth
    def post(self):
        data = request.get_json(silent=True, force=True)
        if not data:
            return {"status": 400, "msg": "Request body must be valid JSON"}, 400
        message = data.get("message")
        if not message:
            return {"status": 400, "msg": "message is required"}, 400
        users.update_one(
            {"Username": request.username},
            {"$push": {"Messages": message}}
        )
        return {"status": 200, "msg": "Message has been saved successfully"}, 200

Acceptance Criteria

  • Save.post() uses a single update_one with $push — no prior get_user_messages call
  • Concurrent save requests no longer risk overwriting each other
  • Unit tests updated to reflect the new implementation
  • get_user_messages helper retained for use by Retrieve

Complexity Estimate

XS — three lines replaced, no new dependencies.

Priority

Medium — correctness (race condition) justifies fixing even in a tutorial; also teaches idiomatic MongoDB.


Auto-identified by workspace issue-logger
Category: code optimisation / performance
Complexity: XS
Repository: DewaldOosthuizen/python_rest_tutorial

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions