Skip to content

Commit bca9516

Browse files
committed
viewpoint with examples
1 parent d95b26f commit bca9516

File tree

1 file changed

+50
-43
lines changed

1 file changed

+50
-43
lines changed

graph/patterns/viewpoint.md

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,35 @@
1-
# Pattern name
1+
# Viewpoint
22

33
Microsoft Graph API Design Pattern
44

5-
*Provide a short description of the pattern.*
6-
The viewpoint pattern provides the ability to manage an individual status of a shared object for multiple independent actors.
75

8-
## Problem
9-
10-
Often in an organizational context a group of people receives a common messages but different users act on this messages at a different point of time.So that if user1 read and deleted the message, for user2 this is still unread. usually it happens when a shared item is presented in an individual context.
6+
*The viewpoint pattern provides the ability to manage an individual status of a shared object for multiple independent actors.*
117

8+
## Problem
9+
A shared resource, such as a website or a group message, may have different states for different users who access it at different times in an organizational context. For example, user1 may read and delete a message, while user2 may not have seen it yet. This usually happens when a shared item is presented in an individual context.
1210
## Solution
1311

14-
*Describe how to implement the solution to solve the problem.*
12+
The viewpoint pattern provides a solution to how to model an individual user context on a shared resource using a `viewpoint` structural property on an API entity type.
13+
For example, the `viewpoint` property can indicate whether a message is read, deleted, or flagged for a given user.
14+
The consistent naming convention ensures that when a developer uses Graph APIs all ‘viewpoints’ structural properties represent type specific user context across different M365 services and features.
1515

16-
Represents user view points data for a serviceUpdateMessage.
17-
Represents user viewpoints data of the service message. This data includes message status such as whether the user has archived, read, or marked the message as favorite. This property is null when accessed with application permissions.
18-
https://learn.microsoft.com/en-us/graph/api/resources/serviceupdatemessage?view=graph-rest-1.0
19-
20-
## When to use this pattern
16+
This pattern simplifies the API client logic by hiding the state transition details and providing state persistency on the server side. The server can manage the different viewpoints for the shared resource without exposing them to the client. You should also make this property filterable.
17+
## Issues and considerations
2118

22-
*Describe when and why the solution is applicable and when it might not be.*
23-
<Annotations Target="microsoft.graph.approvalItem/viewPoint">
19+
- Because the `viewpoint` property reflects an individual user's context, it is null when accessed with application permissions.
20+
- Sometimes, the viewpoint can be computed on the server. In this case, an API producer should add OData annotations to the property to provide more information for downstream tools, such as SDKs and documentation generation.
21+
```
22+
<Annotations Target="microsoft.graph.approvalItem/viewPoint">
2423
<Annotation Term="Org.OData.Core.V1.Computed" Bool="true" ags:OwnerService="Microsoft.Approvals" />
25-
</Annotations>
26-
27-
## Issues and considerations
24+
</Annotations>
25+
```
26+
- An alternative to this design would be to store the user state on the client side. However, this may be problematic in some cases, because of the many devices that a user may have and the need to synchronize the state across them.
2827

29-
*Describe tradeoffs of the solution.*
28+
## Examples
3029

31-
## Example
32-
https://microsoftgraph.visualstudio.com/onboarding/_search?action=contents&text=chatViewpoint&type=code&lp=code-Project&filters=ProjectFilters%7Bonboarding%7DRepositoryFilters%7Bonboarding%7D&pageSize=25&result=DefaultCollection/onboarding/onboarding/GBmaster//reviews/15279-ga-chat-lastMessagePreview/api.md
30+
### Defining a viewpoint
3331

34-
<Annotations Target="microsoft.graph.approvalItem/viewPoint">
35-
<Annotation Term="Org.OData.Core.V1.Computed" Bool="true" ags:OwnerService="Microsoft.Approvals" />
36-
</Annotations>
37-
*Provide a short example from real life.*
32+
The following example demonstrates how to define the 'viewpoint' property for the `chat` entity, where a chat is a collection of chatMessages between one or more participants:
3833
```
3934
<ComplexType Name="chatViewpoint" ags:WorkloadIds="Microsoft.Teams.GraphSvc">
4035
<Property Name="isHidden" Type="Edm.Boolean" />
@@ -44,26 +39,17 @@ https://microsoftgraph.visualstudio.com/onboarding/_search?action=contents&text=
4439
<EntityType Name="chat" BaseType="graph.entity" ags:OwnerService="Microsoft.Teams.GraphSvc">
4540
<Property Name="chatType" Type="graph.chatType" Nullable="false" />
4641
<Property Name="createdDateTime" Type="Edm.DateTimeOffset" />
47-
<Property Name="lastUpdatedDateTime" Type="Edm.DateTimeOffset" />
48-
<Property Name="onlineMeetingInfo" Type="graph.teamworkOnlineMeetingInfo" />
49-
<Property Name="tenantId" Type="Edm.String" />
42+
<Property Name="lastUpdatedDateTime" Type="Edm.DateTimeOffset" />
5043
<Property Name="topic" Type="Edm.String" />
5144
<Property Name="viewpoint" Type="graph.chatViewpoint" />
52-
<Property Name="webUrl" Type="Edm.String" />
53-
<NavigationProperty Name="assignedSensitivityLabel" Type="graph.sensitivityLabel" ContainsTarget="true" ags:IsHidden="true" />
54-
<NavigationProperty Name="installedApps" Type="Collection(graph.teamsAppInstallation)" ContainsTarget="true" />
55-
<NavigationProperty Name="lastMessagePreview" Type="graph.chatMessageInfo" ContainsTarget="true" />
56-
<NavigationProperty Name="members" Type="Collection(graph.conversationMember)" ContainsTarget="true" />
57-
<NavigationProperty Name="messages" Type="Collection(graph.chatMessage)" ContainsTarget="true" />
58-
<NavigationProperty Name="operations" Type="Collection(graph.teamsAsyncOperation)" ContainsTarget="true" />
59-
<NavigationProperty Name="permissionGrants" Type="Collection(graph.resourceSpecificPermissionGrant)" ContainsTarget="true" />
60-
<NavigationProperty Name="pinnedMessages" Type="Collection(graph.pinnedChatMessageInfo)" ContainsTarget="true" />
45+
...
6146
<NavigationProperty Name="tabs" Type="Collection(graph.teamsTab)" ContainsTarget="true" />
6247
</EntityType>
6348
6449
```
50+
### Reading an entity with a viewpoint
6551

66-
52+
The following example shows reading a collection of chats for an identified user, with a viewpoint for each chat:
6753

6854
```http
6955
GET https://graph.microsoft.com/v1.0/users/8b081ef6-4792-4def-b2c9-c363a1bf41d5/chats
@@ -82,9 +68,7 @@ Content-type: application/json
8268
"topic": "Meeting chat sample",
8369
"createdDateTime": "2020-12-08T23:53:05.801Z",
8470
"lastUpdatedDateTime": "2020-12-08T23:58:32.511Z",
85-
"chatType": "meeting",
86-
"lastMessagePreview": {...}
87-
,
71+
"chatType": "meeting",
8872
"viewpoint":{
8973
"lastMessageReadDateTime": "2021-03-28T21:10:00.000Z" // User has unread messages
9074
}
@@ -94,12 +78,35 @@ Content-type: application/json
9478
"topic": "Group chat sample",
9579
"createdDateTime": "2020-12-03T19:41:07.054Z",
9680
"lastUpdatedDateTime": "2020-12-08T23:53:11.012Z",
97-
"chatType": "group",
98-
"lastMessagePreview": null, // No message was sent in this group chat yet
81+
"chatType": "group",
9982
"viewpoint":{
10083
"lastMessageReadDateTime": "0000-01-01T00:00:00.000Z" // User hasnt read anything since no message was posted
10184
}
10285
}
10386
]
10487
}
105-
```
88+
```
89+
### Updating a viewpoint
90+
91+
You can update the `viewpoint` property only if the server does not compute it automatically. Updating the `viewpoint` property usually has a side effect, so you should use an OData action to perform the update.
92+
93+
The following example shows marking a chat as read for a user:
94+
95+
```http
96+
97+
POST https://graph.microsoft.com/beta/chats/19:7d898072-792c-4006-bb10-5ca9f2590649_8ea0e38b-efb3-4757-924a-5f94061cf8c2@unq.gbl.spaces/markChatReadForUser
98+
Content-Type: application/json
99+
Content-length: 106
100+
101+
{
102+
"user": {
103+
"id" : "d864e79f-a516-4d0f-9fee-0eeb4d61fdc2",
104+
"tenantId": "2a690434-97d9-4eed-83a6-f5f13600199a"
105+
}
106+
}
107+
```
108+
The server responds with a success status code and no payload:
109+
110+
```http
111+
HTTP/1.1 204 No Content
112+
```

0 commit comments

Comments
 (0)