Skip to content

Commit 8fc6ca4

Browse files
authored
Merge pull request #302 from baywet/feature/ctncn
change notifications and change tracking patterns
2 parents b136f08 + cde128a commit 8fc6ca4

File tree

2 files changed

+129
-16
lines changed

2 files changed

+129
-16
lines changed

graph/deprecation.md

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,21 @@ to annotate any usages of that type.
1616

1717
**Example of property annotation:**
1818

19-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20-
<EntityType Name="outlookTask" BaseType="Microsoft.OutlookServices.outlookItem" ags:IsMaster="true" ags:WorkloadName="Task" ags:EnabledForPassthrough="true">
21-
<Annotation Term="Org.OData.Core.V1.Revisions">
22-
<Collection>
23-
<Record>
24-
<PropertyValue Property = "Date" Date="2022-03-30"/>
25-
<PropertyValue Property = "Version" String="2022-03/Tasks_And_Plans"/>
26-
<PropertyValue Property = "Kind" EnumMember="Org.OData.Core.V1.RevisionKind/Deprecated"/>
27-
<PropertyValue Property = "Description" String="The Outlook tasks API is deprecated and will stop returning data on June 30, 2024. Please use the new To Do API."/>
28-
<PropertyValue Property = "RemovalDate" Date="2024-06-30"/>
29-
</Record>
30-
</Collection>
31-
</Annotation>
32-
...
33-
</EntityType>
34-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19+
```xml
20+
<EntityType Name="outlookTask" BaseType="Microsoft.OutlookServices.outlookItem" ags:IsMaster="true" ags:WorkloadName="Task" ags:EnabledForPassthrough="true">
21+
<Annotation Term="Org.OData.Core.V1.Revisions">
22+
<Collection>
23+
<Record>
24+
<PropertyValue Property = "Date" Date="2022-03-30"/>
25+
<PropertyValue Property = "Version" String="2022-03/Tasks_And_Plans"/>
26+
<PropertyValue Property = "Kind" EnumMember="Org.OData.Core.V1.RevisionKind/Deprecated"/>
27+
<PropertyValue Property = "Description" String="The Outlook tasks API is deprecated and will stop returning data on June 30, 2024. Please use the new To Do API."/>
28+
<PropertyValue Property = "RemovalDate" Date="2024-06-30"/>
29+
</Record>
30+
</Collection>
31+
</Annotation>
32+
</EntityType>
33+
```
3534

3635
When the request URL contains a reference to a deprecated model element, the gateway will add a [Deprecation
3736
header](https://tools.ietf.org/html/draft-dalal-deprecation-header-02) (with the

graph/patterns/change-tracking.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Change Tracking
2+
3+
Microsoft Graph API Design Pattern
4+
5+
*The change tracking pattern provides the ability to keep API consumers in sync with changes in Microsoft Graph without having to continuously poll the API.*
6+
7+
## Problem
8+
---------
9+
10+
API consumers require an efficient way to keep data in sync with Microsoft Graph, and the API design should be optimized to avoid polling as it is costly for consumers and producers alike as well as wouldn't guarantee data integrity.
11+
12+
## Solution
13+
--------
14+
15+
API designers can enable the change tracking (delta) capability on entity collections by declaring a delta function for API consumers to use to track changes in that collection.
16+
17+
This new endpoint can be used to sync API consumers. This is achieved through returning a delta link with a watermark. Once the API consumer needs to refresh the data it uses the last provided delta link to catch up on new changes since their last request. Delta guarantees integrity of data through the watermark, regardless of service partitions and other obscure aspects for clients.
18+
19+
> Note: although this capability is similar to the [OData $delta feed](https://docs.oasis-open.org/odata/odata-json-format/v4.0/errata02/os/odata-json-format-v4.0-errata02-os-complete.html#_Toc403940644) capability, it is a different construct. Microsoft Graph APIs MUST provide change tracking through the delta function and MUST NOT implement the OData $delta feed when providing change tracking capabilities to ensure the uniformity of the API experience.
20+
21+
## Issues and Considerations
22+
-------------------------
23+
24+
Implementer MUST implement a watermark storage system in case of active watermarks. Passive watermarks are watermarks that can be retrieved from the context (e.g. timestamp), active watermarks represent information required to track the sync state which cannot be retrieved from the context (e.g. cursor from data store, partition affinity marker, partition id, generated unique sync identifier...)
25+
26+
Implementer MUST implement soft deletion for entities in the backend storage system. The soft deletion will provide useful information to the client to appropriately reflect deletions.
27+
28+
When an entity is soft deleted, the delta function MUST return the id of the deleted entity as well as a `@removed` annotation with the `reason` field.
29+
- The reason MUST be set to `changed` if the entity can be restored. `"@removed": {"reason": "changed"}`.
30+
- The reason MUST be set to `deleted` if the entity cannot be restored. `"@removed": {"reason": "deleted"}`.
31+
32+
When a link to an entity is deleted, or when the linked entity is deleted, or when a link to an entity is added, implementer MUST return a `property@delta` annotation. e.g. considering the entity Group has a navigation property named members of type Collection(user):
33+
34+
- When a user is added to the group `"members@delta": [{ "@odata.type": "#microsoft.graph.user", "id of the added user"}]`
35+
- When a user is removed from the group, or the target user is deleted `"members@delta": [{"@removed": {"reason": "deleted"}, "id of the deleted or removed user"}]`
36+
37+
> Note: the delta function also provides support for $filter and $select to allow the API consumer to narrow down the number of entities and properties retrieved as well as the number of changes that are tracked. Additionally the delta function can also support $top to allow the API consumer to sync smaller sets of changes as well as $expand to allow the API consumer to sync related data. Expand across workloads is not supported today however.
38+
39+
## When to Use this Pattern
40+
------------------------
41+
42+
Before using the change tracking pattern in your API definition, make sure your scenario fits the following criteria:
43+
44+
- API consumers want to sync the data.
45+
- API consumers don't want to be immediately notified of changes. (see change notifications pattern for this scenario).
46+
- API consumers are not looking for a "one-time" export or back-up mechanism.
47+
48+
### Alternatives
49+
50+
- Change notifications pattern (TODO add link when described)
51+
- Backup pattern (TODO)
52+
53+
## Examples
54+
-------
55+
56+
### Getting changes for the users entity set
57+
58+
```HTTP
59+
GET https://graph.microsoft.com/v1.0/users/delta
60+
```
61+
62+
```json
63+
{
64+
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users",
65+
"@odata.deltaLink": "https://graph.microsoft.com/v1.0/users/delta?$deltatoken=mS5DuRZGjVL-abreviated",
66+
"value": [
67+
{
68+
"businessPhones": [
69+
"+1 309 555 0104"
70+
],
71+
"displayName": "Grady Archie",
72+
"givenName": "Grady",
73+
"jobTitle": "Designer",
74+
"mail": "[email protected]",
75+
"officeLocation": "19/2109",
76+
"preferredLanguage": "en-US",
77+
"surname": "Archie",
78+
"userPrincipalName": "[email protected]",
79+
"id": "0baaae0f-b0b3-4645-867d-742d8fb669a2",
80+
"manager@delta": [
81+
{
82+
"@odata.type": "#microsoft.graph.user",
83+
"id": "99789584-a1e1-4232-90e5-866170e3d4e7"
84+
}
85+
]
86+
},
87+
{
88+
"id": "0bbbbb0f-b0b3-4645-867d-742d8fb669a2",
89+
"@removed": {
90+
"reason": "changed"
91+
}
92+
}
93+
]
94+
}
95+
```
96+
97+
> Note: the response contains an `@odata.deltaLink` instance annotation with the watermark only when all the changes are enumerated. If more changes need to be enumerated, the response instead contains an `@odata.nextLink` instance annotation the application can request right away to get the next page.
98+
99+
### CSDL example
100+
101+
```xml
102+
<Function Name="delta" IsBound="true">
103+
<Parameter Name="bindingParameter" Type="Collection(Microsoft.DirectoryServices.user)" />
104+
<ReturnType Type="Collection(Microsoft.DirectoryServices.user)" />
105+
</Function>
106+
107+
<EntitySet Name="users" EntityType="microsoft.graph.user">
108+
<Annotation Term="Org.OData.Capabilities.V1.ChangeTracking">
109+
<Record>
110+
<PropertyValue Property="Supported" Bool="true" />
111+
</Record>
112+
</Annotation>
113+
</EntitySet>
114+
```

0 commit comments

Comments
 (0)