Name: DELETE Endpoints
Status: approved
Created: 2023-01-10
Updated: 2023-01-10

DELETE Endpoints (#135)

APIs should provide a delete method for resources unless it is not valuable for users to do so.

If the user does not have permission to access the resource, regardless of whether or not it exists, the service must error with HTTP 403: Permission Denied. Permission must be checked prior to checking if the resource exists.

If the user does have proper permission, but the requested resource does not exist or has been soft deleted, the service must error with HTTP 404: Not Found.

When an entity is successfully deleted, the endpoint must return HTTP 204: No Content

Rationale

Responding with 204 is a technically correct response due to DELETE being an idempotent action. You can apply it many times and the end result is the same - the resource is deleted.

However, if a consumer sends the wrong ID they may incorrectly assume that their data has been deleted. In this instance a 204 for successful delete and a 404 (or 410 if we do soft deletes) is appropriate.

Finally, we surveyed existing APIs in the wild and all returned a 404 when a non-existant ID was provided:

  • GitHub: 404
  • LaunchDarkly: 404
  • Zalando: 404

Cascading Delete

Some resources have a hierarchical or associative relationship with other resources. In some cases, deleting a resource will necessarily delete all of its children in the hierarchy. In other cases, a deletion of a common resource will remove its association with other resources, altering their behavior. Since resource deletion can potentially delete or affect more than the user realized, a force query parameter can be required.

For cases where protection against cascades or severed relationships is desired:

  • the decision of which related resources are protected and which are not can be decided on a per-API basis
  • if no protected resources will be affected, a target resource can be deleted with a normal DELETE request
    • e.g., a parent resource being deleted currently has no child resources
    • e.g., a common resource being deleted is not associated with or referenced by any other resources
  • if deletion will affect protected resources, a query param force=true must be included to complete the deletion request
    • if the query param is not present with a value of true, return 400
      • the response must include a messsage indicating which type of resources are preventing a successful deletion
    • if the query param is present, delete all child resources and any relationships with other resources, and return 204

For cases where protection against cascades or severed relationships is not necessary, the force parameter is not required and the delete may affect related resources.