Skip to main content
Adopt

IPA-108: Delete

In REST APIs, it is customary to make a DELETE request to a resource's URI (for example, /groups/{groupId}/clusters/{clusterName}) to delete that resource.

Guidance

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

    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    responses:
    "204":
    description: The cluster was deleted.
    Why:

    The clusters resource lets users remove a cluster, so it exposes a Delete method via DELETE on the resource URI.

    1. For each resource in the spec, determine whether users need to delete instances of it.

    2. Confirm the resource is neither read-only nor a singleton — both must not have a Delete method.

    3. If deleting a resource is valuable for users, confirm the resource exposes a DELETE method. Flag resources that omit it without a clear reason.

  2. The HTTP verb must be DELETE

    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    responses:
    "204":
    description: The cluster was deleted.
    Why:

    The delete operation uses DELETE on the resource URI, the HTTP verb defined for removing a resource.

  3. The response should be empty

    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    responses:
    "204":
    description: The cluster was deleted.
    Why:

    The delete operation returns an empty body with a 204 No Content status, signaling success without returning a representation.

    1. For the delete operation, inspect the success response.

    2. Confirm the response has no body.
    3. Confirm an empty response uses the 204 No Content status code. Flag delete operations that return a body or a different success status.

  4. The request must not include a body

    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    parameters:
    - name: clusterName
    in: path
    required: true
    schema:
    type: string
    responses:
    "204":
    description: The cluster was deleted.
    Why:

    The delete operation identifies the resource entirely through the path and defines no requestBody.

  5. The Delete method must succeed if and only if a resource was present and was successfully deleted

    • If the resource did not exist, the method must respond with a 404 Not Found error
    • The Delete method must not return a successful response while any of the resource's internal state remains — settings, policies, or configurations the client can only manage through the resource itself
    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    responses:
    "204":
    description: The cluster and all of its internal state were deleted.
    "404":
    description: No cluster with that name exists.
    Why:

    The delete operation succeeds with 204 only when the cluster existed and was fully removed, internal state included, and returns a 404 Not Found error when the resource was not present.

    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    responses:
    "204":
    description: The cluster was deleted; its backup policy is retained.
    Why:

    The delete reports success while the cluster's backup policy — internal state the client can only manage through the cluster itself — survives. The resource is not fully gone, so a client cannot treat the 204 as a clean teardown. The operation also omits 404 Not Found for the absent-resource case.

    1. Delete a resource that exists and confirm the method succeeds.

    2. Confirm no internal state of the resource — settings, policies, or configurations the client can only manage through the resource itself — survives the delete.

    3. Issue the same delete against a resource that does not exist.

    4. Confirm the second call responds with a 404 Not Found error rather than reporting success.

Example

DELETE /groups/${groupId}/clusters/${clusterName}

Cascading Delete

Sometimes, it may be necessary for users to be able to delete a resource as well as all applicable child resources. However, since deletion is usually permanent, it is also important that users not do so accidentally, as reconstructing wiped-out child resources may be quite challenging.

  1. The API must not automatically delete child resources when a parent resource is deleted.

    {
    "error": 400,
    "reason": "Bad Request",
    "detail": "Please delete all clusters in this project before deleting the project.",
    "errorCode": "BAD_REQUEST",
    "parameters": []
    }
    Why:

    The API fails with a validation error if child resources are present, instead of deleting them. The validation should instruct the user which child resources to delete first.

    1. For each Delete operation, determine whether the resource may have child resources.

    2. If it can, read the Delete operation description and, where available, the handler source it maps to.

    3. Determine whether the operation automatically deletes its child resources.

    4. Report any Delete operation that automatically deletes child resources without a validation error and without explicit opt-in.

  2. If an API allows deletion of a resource that may have child resources, the API should provide a cascading=true query parameter.

    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    parameters:
    - name: cascading
    in: query
    schema:
    type: boolean
    default: false
    responses:
    "204":
    description: The cluster and its child resources were deleted.
    Why:

    The cluster may have child resources, so the delete operation exposes a cascading query parameter that lets users explicitly opt in to deleting them.

    1. For each delete operation, determine whether the resource may have child resources.

    2. If it can, confirm the operation exposes a cascading query parameter.

    3. Flag delete operations on resources with children that omit the cascading parameter, forcing destructive deletes without an explicit opt-in.

Example

DELETE /groups/{groupId}/clusters/{clusterName}?cascading=true

Error Handling

See IPA-114: Errors for guidance on error handling and documentation.

Naming

  1. Operation ID must be unique

    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    Why:

    deleteGroupCluster is not reused by any other operation, so each operation in the spec has a distinct identifier.

  2. Operation ID must be in camelCase

    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    Why:

    deleteGroupCluster is camelCase: lowercase first word, each subsequent word capitalized, no separators.

  3. Operation ID must start with the verb "delete"

    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    Why:

    The operation ID begins with the verb delete, identifying it as a delete method.

  4. Operation ID should be followed by a noun or compound noun

    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    Why:

    The verb delete is followed by the compound noun GroupCluster, naming the resource being deleted.

  5. The noun(s) in the Operation ID should be the collection identifiers from the resource identifier in singular form

    paths:
    /groups/{groupId}/clusters/{clusterName}:
    delete:
    operationId: deleteGroupCluster
    Why:

    The resource identifier /groups/${groupId}/clusters/${clusterName} has collection identifiers groups and clusters; the operation ID uses their singular forms, Group and Cluster.

Examples:

Resource IdentifierOperation ID
/groups/${groupId}/clusters/${clusterName}deleteGroupCluster