Web Application Design: Deletes resource, hard and soft
I talked about the “nomenlature knot” in the last post but after trying to write about it a few times, I came to realize this topic has more rabbit holes than Watership Down. So, I’m deferring my post(s) and maybe starting a new series on it. Since I would rather move forward with the next posts in this series, lets go on with variations on delete actions.
Lots of applications complicate or even replace the action of deleting resources but preserve for the user the notional interface of deletion. There’s many good reasons for this–mainly to smooth recovery from accidents with an “undoable” delete. I usually hear this called a “soft delete”. Lets examine a “soft delete” feature, discuss what makes this different from a “hide” feature, and the setup for a “hard delete” which actually deletes something.
Here’s a feature description for “soft delete”
Given a user visiting the view for Wat
When the user clicks on the delete button to submit the Wat delete request
Then the Wat property "deleted_at" is updated with the current datetime
And the user redirected to Wat index view
And the "deleted" Wat is not shown on the index
And the user is presented with an alert informing that the Wat resource was deleted
This is the same feature we might write for a normal delete but
instead of deleting the feature we are updating a property of the
resource: in our example, deleted_at
is updated with a current
datetime.
This feature description could be fairly criticized as being too bound up in the implementation details of the model for a proper “behavior driven development” feature definition. But the effects have to be specified somewhere and the justification for that implementation also. For this discussion, we have to know that instead of deleting a record in a DB, we’re updating a property of that record.
We’ll examing two options for implementing it:
- change the “delete” button to send a hidden form updating the
deleted_at
- change the
WatsController#delete
action to updateWat#deleted_at
instead
Let’s go.
Delete button sends update request
What’s nice about this implentation is that, the pretense of deletion is implemented by client labeling, and the API action is “normal” even though it’s not what the user interface says is happening. This implementation is most amenable if the “deleted” resources are exposable and manageable by users, in which case, maybe the semantics of the whole feature should be reconsidered. Perhaps instead of “delete” and “undelete” the actions should be labeled with “hide” and “show” or “remove” and “restore” or something like that.
This sort of “conceal/reveal” semantics should probably be reflected
in the model, which may mean rewriting the feature description. There
could be different kinds perhaps implemented different ways for
different properties. That’ll have to be discussed in a different post
though. For this post, allow, that, if we’re not updated a property
called deleted_at
, we could just as easily be updating a property
with more semantically appropriate name.
Delete action updates property
Here the server owns the feature, and client’s actions are co-opted to implement the “soft delete”. This is good if the feature should be hidden from the users and clients. However if so, we require other sorts of management features for dealing with the “deleted” features.
Summary and conclusion
The soft delete works through filtering–the index view automatically
excludes the deletion property we called deleted_at
. Some questions
to ask are:
- When is exposing the deletion property to the client desirable?
- How can users see a list of “deleted” resources?
- How can users reverse or “undelete” deleted resources?
- How can a resource be “hard deleted”?
- automatic “garbage collection” process
- administrative delete action
- How can “lifecycle” changes like this be logged, reported on, or audited?
- What/How are associated resources effected by this kind of “delete”? (grateful thanks to the reader who suggested this)
If soft deleted resources are managable by users, I think it’s worth considering whether the semantics should be shifted to a “hide/show” sort of labelling. The property to be updated would be changed, and the controls labeled for concealing and revealing resources.
This feature’s dependency on what I’m just going to call “application semantics” really stands out to me in a way that didn’t with the copy features. I’m planning to write about “conceal/reveal” features soon-if-not-next. But I’m going to have to come up with a way to talk oabout this “application semantics” thing also.