It is a fairly common requirement to support undeletes or delayed/batched deletions for data services. What I'm wondering is how to implement this in a RESTful way. I'm torn between a few different options (none of which seems terribly attractive to me). Common across these different options, I believe, is the need for an API which returns all resource marked as deleted for a particular resource type.
Here are some options I've thought about and some of their pros/cons:
Options to mark resource as deleted:
- Use HTTP DELETE to mark the resource as deleted.
- Use HTTP PUT/POST to update deleted flag. This doesn't feel right since it maps what is essentially a deletion away from the HTTP DELETE method and into other HTTP methods.
Options when GET-ing resource marked for deletion:
- Return HTTP Status 404 for a resource marked as deleted. Clean & transparent, but how do we tell the difference between a resource that is really deleted vs. one just marked as deleted.
- Return HTTP Status 410. Provides way to tell the difference, but 410 technically says it "is expected to be considered permanent. Clients with link editing capabilities SHOULD delete references to the Request-URI after user approval." There may be enough wiggle room in the words "expected" and "SHOULD" here. Not sure how well 410 is supported/understood out there in clients.
- Return HTTP Status 200 and include flag field indicating resource is deleted. This seems wierd since the idea of deleting it in the first place was because you actually wanted it to not appear. This pushes responsibility for filtering out deleted resources down to clients.
Options for responses which include this deleted resource:
- Omit the resources makred as deleted. Clean & simple. But what if you actually want to know about deleted resources.
- Include them along with field indicating that they are deleted. This pushes responsibility for filtering out deleted resources down to clients. It makes pagination tricky if you want to only page through active or deleted resources.
Options when updating a resource marked for deletion:
- Use HTTP Status 404. The resource is gone right? But, how can you tell the difference between a resource marked as deleted and one actually deleted. HTTP body in 404 response could disambiguate here but then clients are left with parsing/interpreting your body to disambiguate. Maybe response header might help here? Which one? Custom header?
- Use HTTP Status 409 with message about how resource must first be undeleted.
Options to undelete resource marked for deletion:
- Use HTTP PUT/POST for update operation of resource and mark it as active again. This only works as long as you're not returning an HTTP 404 for the GET operation for the resource since it doesn't make since to PUT/POST to a resource that is "Not found" (404).
- Use HTTP PUT/POST for creation operation of resource. The problem here is which data takes precedence? The data sent up in the create operation? Or the data that is being undeleted? filter it out of any other queries that would have returned it. Then, treat the HTTP PUT/POST that creates the resource as an undelete if the resource identifier points to a resource marked as deleted.
- Separate REST path dedicated to undelete resources marked for deletion.
This is by no means an exhaustive list. I just wanted to enumerate some of the options that have been bouncing around in my head.
I know the answer to how to do this is, as usual, "it depends". What I'm curious about is what qualifications/requirements would you use to make your decision? How have you seen this implemented or implemented it yourself?