Skip to content

Commit 5a6465d

Browse files
committed
Update change-notification.md
1 parent 4679cf0 commit 5a6465d

File tree

1 file changed

+130
-10
lines changed

1 file changed

+130
-10
lines changed

graph/patterns/change-notification.md

Lines changed: 130 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,149 @@
22

33
Microsoft Graph API Design Pattern
44

5-
*Provide a short description of the pattern.*
5+
*The change tracking pattern provides the ability for API consumers to request changes in data from Microsoft Graph without having to re-read data that has not changed.*
66

77

88
## Problem
99

10-
*Describe the business context relevant for the pattern.*
11-
12-
*Provide a short description of the problem.*
10+
API consumers require an efficient way to acquire changes to data in Microsoft Graph, for example to synchronize an external store or to drive a change-centric business process.
1311

1412
## Solution
1513

16-
*Describe how to implement the solution to solve the problem.*
14+
API designers can enable the change tracking (delta) capability on a resource in the Graph (typically on an entity collection or a parent resource) by declaring a delta function on that resource.
1715

18-
*Describe related patterns.*
16+
This function returns a delta payload. A delta payload consists of a collection of annotated full or partial entities in standard Graph format plus either a nextLink to further pages of original or change data that are immediately available OR a deltaLink to poll to get the next set of changes as they occur.
17+
Annotations allow the delta payload to indicate resources or links which have been deleted. API callers are expected to differentiate resource adds from updates by interpreting the id property of the change records against the existence of resources in whatever external system is doing the processing.
1918

2019
## When to use this pattern
2120

22-
*Describe when and why the solution is applicable and when it might not be.*
21+
API consumers want a pull mechanism to request and process change to Graph data, either via proactive polling or by responding to Graph notifications.
22+
API producers can provide a low data latency (sub-minute at P95).
23+
When API consumers need guaranteed data integrity over the set of changes to Graph data.
2324

2425
## Issues and considerations
2526

26-
*Describe tradeoffs of the solution.*
27+
- The pattern requires a sequence of requests.
28+
29+
1. GET request on the delta function, which returns the first page of the current state of the resources that delta applies to.
30+
2. [Optionally] Further GET requests to retrieve more pages of the current state via the odata.nextLink.
31+
3. After some time, a GET request to see if there are new changes via the odata.deltaLink.
32+
4. [Optionally] GET requests to retrieve more pages of changes via the odata.nextLink.
33+
34+
API producers MAY respond to standard Graph OData query parameters with the initial call to the delta function:
35+
36+
- `$select` to enforce the set of properties on which change is reported.
37+
- `$filter` to influence the range of changes returned.
38+
- `$expand` to include linked resources with the set of changes.
39+
- `$top` parameter to influence the size of the set of change records.
40+
41+
These query parameters MUST be encoded into subsequent odata.nextLink or odata.deltaLink, such that the same options are preserved through the call sequence without callers respecifying them, which MUST NOT be allowed.
42+
43+
Making a sequence of calls to a delta function followed by the opaque urls in the “nextLink” and “deltaLink” MUST guarantee that the data at the start time of the call sequence and all changes to the data thereafter will be returned at least once. It is not necessary to avoid duplicates in the sequence. When the delta function is returning changes, they MUST be sequenced chronologically refer to [public documentation](https://learn.microsoft.com/en-us/graph/delta-query-overview?view=graph-rest-1.0) for more details.
44+
45+
- The delta function can be bound to a collection, as with
46+
`/users/delta` – this returns the changes to the users' collection.
47+
48+
or to some logical parent resource, where the change records are implied to be relative to all collections contained within the parent, for example
49+
`/me/planner/all/delta` – this returns changes to any resource within planner that a user is subscribed to as a heterogenous collection.
50+
- Delta payload requirements [OData spec](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_DeltaPayloadResponse)
51+
- The payload is a collection of change records using the standard Graph collection format.
52+
- The change records are full or partial representations of the resources that changed using the standard Graph types for the resources.
53+
- When a change representing a resource update is included in the payload the API producer MAY return either the changed properties or the full entity. The id of the resource MUST be included in every change record. - The nextLink provides a mechanism to do server-driven paging through the change data that is currently available. When there are no further pages of changes immediately available, a deltaLink is returned instead.
54+
- The deltaLink provides a mechanism for the API consumer to catch up on changes since their last request to the delta function, deltaLink or last page’s nextLink. If no changes have happened since the last request, then the deltaLink MUST return an empty collection.
55+
- Both “nextLink” and “deltaLink” MUST be considered opaque URLs. The best practice is to make them opaque via encoding.
56+
- When an entity is deleted, the delta function MUST return the ID of the deleted entity as well as an @removed annotation with the reason field.
57+
- When an entity is deleted, the reason MUST be set to “changed” if the entity can be restored.
58+
- When an entity is deleted. the reason MUST be set to “deleted” if the entity cannot be restored.
59+
- There is no mechanism to indicate that a resource has entered or exited the dataset based on a change that causes it to match or no longer match any $filter query parameter.
60+
- When a link to an entity is deleted, when the linked entity is deleted, or when a link to an entity is added, the implementer MUST return a “property@delta” annotation.
61+
- When a link to an entity is deleted, but the entity still exists, the reason MUST be set to “changed”.
62+
- When a link to an entity is deleted along with the entity, the reason MUST be set to “deleted”.
63+
- OData query parameters must be honored in full, or a 400-error returned.
64+
65+
## Alternatives ##
66+
67+
- Change notifications pattern with rich payloads – for use cases where API consumers would find calling back into Graph onerous and absolute integrity guarantees are less critical.
68+
69+
70+
## Examples
71+
72+
### Delta payload
73+
74+
Here, a user resource is updated, and there is one user added to and one removed from that user’s directReports collection. Additionally, a second user is deleted. In this case, there are no further pages of change records currently available.
75+
76+
```
77+
GET https://graph.microsoft.com/v1.0/users/delta
78+
79+
{
80+
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users",
81+
"@odata.deltaLink": "https://graph.microsoft.com/v1.0/users/delta?$deltatoken=mS5DuRZGjVL-abreviated",
82+
"value": [
83+
{
84+
"businessPhones": ["+1 309 555 0104"],
85+
"displayName": "Grady Archie",
86+
"givenName": "Grady",
87+
"jobTitle": "Designer",
88+
"mail": "[email protected]",
89+
"officeLocation": "19/2109",
90+
"preferredLanguage": "en-US",
91+
"surname": "Archie",
92+
"userPrincipalName": "[email protected]",
93+
"id": "0baaae0f-b0b3-4645-867d-742d8fb669a2",
94+
"directReports@delta": [
95+
{
96+
"@odata.type": "#microsoft.graph.user",
97+
"id": "99789584-a1e1-4232-90e5-866170e3d4e7"
98+
} ,
99+
{
100+
"id": "66789583-f1e2-6232-70e5-366170e3d4a6",
101+
"@removed": {
102+
"reason": "deleted"
103+
}
104+
}
105+
]
106+
},
107+
{
108+
"id": "0bbbbb0f-b0b3-4645-867d-742d8fb669a2",
109+
"@removed": {
110+
"reason": "changed"
111+
}
112+
}
113+
]
114+
}
115+
```
116+
117+
### API producer CSDL examples
118+
119+
EntitySet example
120+
```
121+
<Function Name="delta" IsBound="true">
122+
<Parameter Name="bindingParameter" Type="Collection(Microsoft.DirectoryServices.user)" />
123+
<ReturnType Type="Collection(Microsoft.DirectoryServices.user)" />
124+
</Function>
125+
<EntitySet Name="users" EntityType="Microsoft.DirectoryServices.user">
126+
<Annotation Term="Org.OData.Capabilities.V1.ChangeTracking">
127+
<Record>
128+
<PropertyValue Property="Supported" Bool="true" />
129+
</Record>
130+
</Annotation>
131+
</EntitySet>
132+
```
27133

28-
## Example
134+
NavigationProperty example
29135

30-
*Provide a short example from real life.*
136+
```
137+
<Function Name="delta" IsBound="true">
138+
<Parameter Name="bindingParameter" Type="Collection(microsoft.education.rostering.api.educationClass)" />
139+
<ReturnType Type="Collection(microsoft.education.rostering.api.educationClass)" />
140+
</Function>
141+
<EntityType Name="educationRoot">
142+
<NavigationProperty Name="classes" Type="Collection(microsoft.education.rostering.api.educationClass)" ContainsTarget="true">
143+
<Annotation Term="Org.OData.Capabilities.V1.ChangeTracking">
144+
<Record>
145+
<PropertyValue Property="Supported" Bool="true" />
146+
</Record>
147+
</Annotation>
148+
</NavigationProperty>
149+
</EntityType>
150+
```

0 commit comments

Comments
 (0)