We'd like to have a consistent and safe way for study designers (almost always the implementers, so people with the DEVELOPER role) to delete and remove things as they set up a study. Often out deletes actually remove things from the database, and so those calls are only accessible to administrators for test clean-up.
Here's how we'll support both through our rest API:
class Apple
boolean deleted - this flag should be part of the public API of the object.
GET /apples?includeDeleted=boolean
- by default, should not include deleted apples
- because deleted apples may be referenced elsewhere, UIs may still need them for labels, etc., so include a flag to return deleted apples, too
GET /apples/id
- always return this item regardless of deletion status so references do not break
- Note: if developers try and delete things to verify they are not referencing older models in their apps, this aspect of our API could be misleading. Their apps will continue to work. Just something to be aware of.
POST /apples
- should not be able to create an apple in a deleted state (deleted always = false)
POST /apples/id
- should be able change the deleted flag if you can update the object
DELETE /apples/id or DELETE /apples?id=x
- sets deleted = false and that's it. This is an option for both developers and administrators.
DELETE /applies/id?physical=true
or DELETE /apples?id=x&physical=true
- physically removes item from database if and only if the caller is an administrator (otherwise falls back to a logical delete)
Physically deleting an entity that's marked as deleted should work, rather than returning a 404. Updating a logically deleted entity to undelete it should work. Otherwise, we continue to return 404 when updating or deleting something that doesn't exist in the database.
Dependent Objects
Objects that cannot be deleted because they would leave other objects with referential integrity problems:
- If the referencing object is logically deleted, the dependent object can be logically deleted;
- If the referencing object is logically deleted, the dependent object cannot be physically deleted
- If the referencing object is physically deleted, then the dependent object can be logically or physically deleted (no longer any constraints)