Skip to content

Commit 1482ce1

Browse files
committed
feat(301): add undelete pattern, replace soft-delete
The current soft-delete pattern has the undesirable side effect of adding special-casing and additional query parameters to the standard methods, as well as possibly impacting their behavior. Introducing undelete, which is a resource oriented solution that achieves much of the same user journeys: - Restoring resources after being deleted. - Listing / getting deleted resources to figure out what is restorable. fixes #111.
1 parent 322db5c commit 1482ce1

File tree

4 files changed

+91
-1
lines changed

4 files changed

+91
-1
lines changed

aep/general/0164/aep.md.j2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Soft delete
22

3+
**NOTE: this pattern is now deprecated, and is no longer valid. Please use [undelete](/undelete) instead.**
4+
35
There are several reasons why a client could desire soft delete and undelete
46
functionality, but one over-arching reason stands out: recovery from mistakes.
57
A service that supports undelete makes it possible for users to recover

aep/general/0164/aep.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
id: 164
3-
state: approved
3+
state: deprecated
44
slug: soft-delete
55
created: 2020-10-06
66
placement:

aep/general/0301/aep.md.j2

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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.

aep/general/0301/aep.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
id: 301
3+
state: approved
4+
slug: undelete
5+
created: 2020-10-06
6+
placement:
7+
category: design-patterns
8+
order: 95

0 commit comments

Comments
 (0)