|
| 1 | +# Undelete |
| 2 | + |
| 3 | +There are several reasons why a client could desire undelete |
| 4 | +functionality, but one over-arching reason stands out: recovery from mistakes. |
| 5 | +A service that supports undelete makes it possible for users to recover |
| 6 | +resources that were deleted by accident. |
| 7 | + |
| 8 | +## Guidance |
| 9 | + |
| 10 | +Services **may** support the ability to "undelete", to allow for situations |
| 11 | +where users mistakenly delete resources and need the ability to recover. |
| 12 | + |
| 13 | +These resources **must** be stored in a separate sibling collection, prefixed with `deleted-`. (e.g. `deleted-books`). Resources deleted will remain in this sibling collection until they expire, or until they are undeleted into the original collection. |
| 14 | + |
| 15 | +Resources that support soft delete **should** have an `expire_time` field on the deleted version of the resource, as described in AEP-148. |
| 16 | + |
| 17 | +### Sibling collection |
| 18 | + |
| 19 | +To implement the undelete pattern, a sibling collection, `deleted-{resource_plural}`, **should** be created where all undeletable resources can be listed and retrieved, as well as undeleted via the `Undelete` custom method: |
| 20 | + |
| 21 | +EXAMPLE TO BE ADDED |
| 22 | + |
| 23 | +### Undelete |
| 24 | + |
| 25 | +The `Undelete` custom method **should** be available. A successful call to this method will: |
| 26 | + |
| 27 | +1. remove the resource from the deleted collection. |
| 28 | +2. restore the resource back into the original collection. |
| 29 | + |
| 30 | +{% tab proto %} |
| 31 | + |
| 32 | +{% sample 'undelete.proto', 'rpc UndeleteBook', 'message UndeleteBookRequest' %} |
| 33 | + |
| 34 | +- The HTTP method **must** be `POST`. |
| 35 | +- The `body` clause **must** be `"*"`. |
| 36 | +- The response message **must** be the resource itself. There is no |
| 37 | + `UndeleteDeletedBookResponse`. |
| 38 | + - The response **should** include the fully-populated resource. |
| 39 | +- A `path` field **must** be included in the request message; it **should** be |
| 40 | + called `path`. |
| 41 | + - The field **should** be [annotated as required][aep-203]. |
| 42 | + - The field **should** identify the [resource type][aep-4] that it |
| 43 | + references. |
| 44 | + - The comment for the field **should** document the resource pattern. |
| 45 | +- The request message **must not** contain any other required fields, and |
| 46 | + **should not** contain other optional fields except those described in this |
| 47 | + or another AEP. |
| 48 | + |
| 49 | +{% tab oas %} |
| 50 | + |
| 51 | +{% sample 'undelete.oas.yaml', '$.paths' %} |
| 52 | + |
| 53 | +- The HTTP method **must** be `POST`. |
| 54 | +- The response message **must** be the resource itself. |
| 55 | + - The response **should** include the fully-populated resource. |
| 56 | +- The operation **must not** require any other fields, and **should not** |
| 57 | + contain other optional query parameters except those described in this or |
| 58 | + another AEP. |
| 59 | + |
| 60 | +{% endtabs %} |
| 61 | + |
| 62 | +### Long-running undelete |
| 63 | + |
| 64 | +Some resources take longer to undelete a resource than is reasonable for a |
| 65 | +regular API request. In this situation, the API **should** follow the |
| 66 | +long-running request pattern AEP-151. |
| 67 | + |
| 68 | +### Errors |
| 69 | + |
| 70 | +If the user calling `Undelete` has proper permission, but the requested |
| 71 | +resource is not deleted, the service **must** error with `409 Conflict`. |
| 72 | + |
| 73 | +For additional guiance, see [errors](/errors). |
| 74 | + |
| 75 | +## Further reading |
| 76 | + |
| 77 | +- For the `Delete` standard method, see AEP-135. |
| 78 | +- For long-running operations, see AEP-151. |
| 79 | +- For resource freshness validation (`etag`), see AEP-154. |
| 80 | +- For change validation (`validate_only`), see AEP-163. |
0 commit comments