I’m developing a REST API for a web application and have concerns about handling concurrent requests. Specifically, when users want to delete items using DELETE requests to endpoints such as /resources/{id}, there’s a chance the resource could have changed since I originally fetched it.
I was considering requiring a timestamp to be sent with the DELETE request. This would ensure that I’m attempting to delete the latest version of that resource, thereby avoiding the risk of accidentally removing the wrong item or one that has been updated recently.
Would this be a good strategy? I haven’t encountered many references to this method but believe it could effectively address concurrency issues. What would be the best way to implement such a precaution?
Your timestamp approach works, but I’d go with version numbers plus proper locking - it’s way more solid. I’ve hit similar concurrency problems in production and we fixed them with database row versioning plus app-level checks. Each resource gets a version field that bumps on updates. For DELETE operations, you have to specify the expected version. If they don’t match, throw a 409 Conflict instead of deleting. Also set proper transaction isolation levels in your database to stop phantom reads during check-and-delete. This pattern saved our asses countless times when multiple clients tried hitting the same resource simultaneously. The trick is making your version check and deletion atomic within one database transaction.
Timestamps work but they’re messy to implement properly. Clock sync between clients and server becomes a headache - what happens when someone’s system clock is wrong? I’ve watched this break things before. Better to combine timestamps with a simple hash of the resource data. That way you know exactly which version they’re trying to delete without depending on precise timing.
Using optimistic concurrency control is a wise approach for managing concurrent requests in REST APIs. Instead of relying on timestamps, consider implementing ETags, which provide a more standardized and effective solution. Upon fetching a resource, your API would send an ETag header. For any DELETE requests, the client must include an If-Match header with this ETag. If the resource has changed by the time the DELETE request is processed, the ETag will not match, resulting in a 412 Precondition Failed error. This prevents accidental deletions by ensuring that clients are notified of any changes and can handle them accordingly by refetching the resource and retrying the operation. This method has proven to be reliable in my experience.