跳轉到

Soft Deletion

Soft deletion in general is a trade-off between permitting users to remove specific information permanently from the API and preventing them from shooting themselves in the foot.

implementation

API definition

abstract class ChatRoomApi {
 @delete("/{id=chatRooms/*}")
 DeleteChatRoom(req: DeleteChatRoomRequest): ChatRoom;

 @get("/chatRooms")
 ListChatRooms(req: ListChatRoomsRequest): ListChatRoomsResponse;

 @post("/{id=chatRooms/*}:expunge")
 ExpungeChatRoom(req: ExpungeChatRoomRequest): void;
}

interface ChatRoom {
 id: string;
 // ...
 deleted: boolean;
 expireTime: Date;
}

interface ListChatRoomsRequest {
 pageToken?: string;
 maxPageSize: number;
 filter?: string;
 includeDeleted?: boolean;
}

interface ListChatRoomsResponse {
 resources: ChatRoom[];
 nextPageToken: string;
}

interface ExpungeChatRoomRequest {
 id: string;
}

why not use the filter field to include the soft-deleted resources?

  • there's no guarantee that all standard list methods will support filtering. In the case that they don't, we'll still need a mechanism to support including soft-deleted resources in the result set.

  • The filter field is responsible for taking a set of possible results and whittling those results down to only those matching a specific set of criteria. The includeDeleted field is responsible for doing the opposite: enlarging the potential result set before even applying the filter.

Exercises

  1. When does it make sense to use a boolean flag versus a state field to represent that a resource has been soft deleted? Does it ever make sense to have both fields on the same resource? Why or why not?
In cases where we don't have a state field of a resource.
It’s perfectly fine to use a state field to keep track of the state of a resource, and then rely on a boolean field to keep track of this single orthogonal aspect of the resource (whether it is soft deleted or not).
  1. How should users indicate that they wish to see only the soft-deleted resources using the standard list method?
ListChatRooms({ filter: "deleted: true", includeDeleted: true, })
  1. What should happen if the custom expunge method is called on a resource that hasn't yet been soft deleted? What about calling the custom undelete method on the same resource?
It should almost always be possible to call the custom expunge method on any resource, whether or not it’s already been soft deleted.
The response should be an error result (e.g., a 412 Precondition Failed HTTP error).
The purpose is, yet again, to make sure users can tell the difference between a request causing a result (imperative) or a result being true but not necessarily caused by a specific reques (declarative).
  1. When does it make sense for soft-deleted resources to expire? How should the expiration deadline be indicated?
In cases where we want to have the recycle bin emptied every so often.
There should be a new field set immediately when a resource is deleted, calculating the expected expiration time according to some predefined policy.
  1. In what circumstances might we consider adding support for soft deletion to be a backward compatible change? What about a backward incompatible change?
The information being deleted isn’t particularly important (e.g., there are no laws governing the disposal of such data).

Summary

  • Soft-deletion refers to the ability to mark a resource as deleted without actually removing it from the API service's storage systems.

  • Typically resources are marked as being deleted using a Boolean flag field called deleted, but they may also add a new deleted state in an already existing state field.

  • Standard method behavior for resources supporting soft deletion require a few minor changes (e.g., the standard get method should not return a 404 Not Found error when a soft-deleted resource is requested).

  • Soft-deleted resources may be restored using a custom undelete method and permanently removed using a custom expunge method.

  • Whichever referential integrity guidelines were in place for the standard delete method (e.g., cascading deletes of referenced resources) should similarly apply for soft deleting resources.