Skip to content

Commit ad75cfb

Browse files
authored
Merge branch 'vNext' into vncz/enum-tips
2 parents c036147 + 4085e6a commit ad75cfb

File tree

4 files changed

+187
-22
lines changed

4 files changed

+187
-22
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# These are the set of folks who should review PRs on the azureRestUpdates branch.
22
* @microsoft/azure-api-stewardship-board @Azure/api-stewardship-board
3+
/graph/* @microsoft/graphguidelinesapprovers

graph/GuidelinesGraph.md

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ Table of contents
88
- [Design approach](#design-approach)
99
- [Naming](#naming)
1010
- [Uniform Resource Locators (URLs)](#uniform-resource-locators-urls)
11-
- [Query support](#query-support)
1211
- [Resource modeling patterns](#resource-modeling-patterns)
1312
- [Pros and cons](#pros-and-cons)
13+
- [Query support](#query-support)
1414
- [Behavior modeling](#behavior-modeling)
1515
- [Error handling](#error-handling)
1616
- [Enums](#enums)
@@ -22,7 +22,7 @@ Table of contents
2222

2323
## Introduction
2424

25-
When building a digital ecosystem API, usability becomes a business priority. The success of your ecosystem depends on APIs that are easy to discover, simple to use, fit for purpose, and consistent across your products.
25+
When building a digital ecosystem API usability becomes a business priority. The success of your ecosystem depends on APIs that are easy to discover, simple to use, fit for purpose, and consistent across your products.
2626

2727
This document offers guidance that Microsoft Graph API producer teams MUST follow to
2828
ensure that Microsoft Graph has a consistent and easy-to-use API surface. A new API design should meet the following goals:
@@ -115,6 +115,7 @@ Following is a short summary of the most often used conventions.
115115
| :ballot_box_with_check: **SHOULD** prefix property names for properties concerning a different entity. | - **Right:** siteWebUrl on driveItem or userId on auditActor <BR> - **Wrong:** webUrl on contact when it's the companyWebUrl |
116116
| :ballot_box_with_check: **SHOULD** prefix Boolean properties with `is`, unless this leads to awkward or unnatural sounding names for Boolean properties. | - **Right:** isEnabled or isResourceAccount <BR>- **Wrong:** enabled or allowResourceAccount <BR> - **Right:** allowNewTimeProposals or allowInvitesFrom (subjectively more natural than the following examples) <BR> - **Wrong:** isNewTimeProposalsAllowed or isInvitesFromAllowed (subjectively more awkward that the preceding examples) |
117117
| :no_entry: **MUST NOT** use collection, response, or request suffixes. | - **Right:** addresses <BR> - **Wrong:** addressCollection |
118+
| :no_entry: **MUST NOT** contain product names. | - **Right:** chatMessages <BR> - **Wrong:** teamsMessages |
118119

119120
### Uniform Resource Locators (URLs)
120121

@@ -149,25 +150,6 @@ In Microsoft Graph, a top-level API category might represent one of the followin
149150

150151
Effectively, top-level categories define a perimeter for the API surface; thus, a new category creation requires additional rigor and governance approval.
151152

152-
### Query support
153-
154-
Microsoft Graph APIs should support basic query options in conformance with OData specifications and [Microsoft REST API Guidelines for error condition responses](https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md#7102-error-condition-responses).
155-
156-
|Requirements |
157-
|----------------------------------------------------------------------------------------------------|
158-
| :heavy_check_mark: **MUST** support `$select on resource` to enable properties projection. |
159-
| :ballot_box_with_check: **SHOULD** support `/entityTypeCollection/{id}?$expand=navProp1` option for navigation properties of entities. |
160-
| :ballot_box_with_check: **SHOULD** support `$filter` with `eq` and `ne` operations on properties of entity collections. |
161-
| :heavy_check_mark: **MUST** support [server-driven pagination](https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md#981-server-driven-paging) of collections using a [nextLink](http://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_ControlInformationnextLinkodatanextL). |
162-
| :ballot_box_with_check: **SHOULD** support [client-driven pagination](https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md#982-client-driven-paging) of collections using `$top` and `$skip` (or `$skipToken`). |
163-
| :ballot_box_with_check: **SHOULD** support `$count` for collections. |
164-
| :ballot_box_with_check: **SHOULD** support sorting with `$orderby` both ascending and descending on properties of the entities. |
165-
166-
The query options part of an OData URL can be quite long, potentially exceeding the maximum length of URLs supported by components involved in transmitting or processing the request. One way to avoid this is to use the POST verb instead of GET with the `$query` segment, and pass the query options part of the URL in the request body as described in the chapter
167-
[OData Query Options](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_PassingQueryOptionsintheRequestBody).
168-
169-
Another way to avoid this is to use JSON batch as described in the [Microsoft Graph batching documentation](https://docs.microsoft.com/graph/json-batching#bypassing-url-length-limitations-with-batching).
170-
171153
### Resource modeling patterns
172154

173155
You can model structured resources for your APIs by using the OData entity type or complex type. The main difference between these types is that an entity type declares a key property to uniquely identify its objects, and a complex type does not. In Microsoft Graph, this key property is called `id` for server-created key values. If there is a natural name for the key property, then the workload can use that.
@@ -238,6 +220,26 @@ Following are a few pros and cons to decide which pattern to use:
238220
> **Note:**
239221
> As can be seen in a few of the pros and cons, one of the important aspects discussed here is that the API design goes beyond the syntactical aspects of the API. Therefore, it is important to plan ahead how the API evolves, lay the foundation, and allow users to form a good understanding of the semantics of the API. **Changing the semantics is always a breaking change.** The different modeling patterns differ in how they express syntax and semantics and how they allow the API to evolve without breaking compatibility. For more information, see [API contract and non-backward compatible changes](#api-contract-and-non-backward-compatible-changes) later in this article.
240222
223+
### Query support
224+
225+
Microsoft Graph APIs should support basic query options in conformance with OData specifications and [Microsoft REST API Guidelines for error condition responses](https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md#7102-error-condition-responses).
226+
227+
|Requirements |
228+
|----------------------------------------------------------------------------------------------------|
229+
| :heavy_check_mark: **MUST** support `$select on resource` to enable properties projection. |
230+
| :ballot_box_with_check: **SHOULD** support `/entityTypeCollection/{id}?$expand=navProp1` option for navigation properties of entities. |
231+
| :ballot_box_with_check: **SHOULD** support `$filter` with `eq` and `ne` operations on properties of entity collections. |
232+
| :heavy_check_mark: **MUST** support [server-driven pagination](https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md#981-server-driven-paging) of collections using a [nextLink](http://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_ControlInformationnextLinkodatanextL). |
233+
| :ballot_box_with_check: **SHOULD** support [client-driven pagination](https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md#982-client-driven-paging) of collections using `$top` and `$skip` (or `$skipToken`). |
234+
| :ballot_box_with_check: **SHOULD** support `$count` for collections. |
235+
| :ballot_box_with_check: **SHOULD** support sorting with `$orderby` both ascending and descending on properties of the entities. |
236+
237+
The query options part of an OData URL can be quite long, potentially exceeding the maximum length of URLs supported by components involved in transmitting or processing the request. One way to avoid this is to use the POST verb instead of GET with the `$query` segment, and pass the query options part of the URL in the request body as described in the chapter
238+
[OData Query Options](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_PassingQueryOptionsintheRequestBody).
239+
240+
Another way to avoid this is to use JSON batch as described in the [Microsoft Graph batching documentation](https://docs.microsoft.com/graph/json-batching#bypassing-url-length-limitations-with-batching).
241+
242+
241243
### Behavior modeling
242244

243245
The HTTP operations dictate how your API behaves. The URL of an API, along with its request/response bodies, establishes the overall contract that developers have with your service. As an API provider, how you manage the overall request/response pattern should be one of the first implementation decisions you make.
@@ -257,6 +259,7 @@ Operation resources must have a binding parameter that matches the type of the b
257259

258260
For a complete list of standard HTTP operations, see the [Microsoft REST API Guidelines error condition responses](https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md#7102-error-condition-responses).
259261

262+
260263
### Error handling
261264

262265
Microsoft REST API Guidelines provide guidelines that Microsoft Graph APIs should follow when returning error condition responses. You can improve API traceability and consistency by using the recommended Microsoft Graph error model and the Microsoft Graph utilities library to provide a standard implementation for your service:
@@ -508,7 +511,8 @@ The guidelines in previous sections are intentionally brief and provide a jump s
508511
| [Namespace](./patterns/namespace.md) | Organize resource definitions into a logical set. |
509512
| [Navigation properties](./patterns/navigation-property.md) | Model resource relationships |
510513
| [Operations](./patterns/operations.md) | Model complex business operations |
511-
| [Type hierarchy](./patterns/subtypes.md) | Model `is-a` relationships using subtypes. |
514+
| [Type hierarchy](./patterns/subtypes.md) | Model `is-a` relationships using subtypes.
515+
| [Viewpoint](./patterns/viewpoint.md) | Model user specific properties for a shared resource.
512516

513517
## References
514518

graph/patterns/antiPatternTemplate.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
# Antipattern name
3+
4+
*name with a negative connotation*
5+
6+
*Example: Flatbag of properties*
7+
8+
## Description
9+
10+
*Example: The flat bag pattern is a known anti-pattern in Microsoft Graph, where multiple variants of a common concept are modeled as a single entity type with all potential properties plus an additional property to distinguish the variants.*
11+
12+
## Consequences
13+
*Describe the consequences in terms of the developer experience*
14+
15+
*Example: This is the least recommended modeling choice because it is weakly typed, which increases the number of variations and complexity of solutions, making it difficult to verify the semantic correctness of the API for both clients and producers...*
16+
17+
## Preferable solutions
18+
19+
*Example: It is preferable to use type hierarchy and facets patterns.
20+
Should provide a link to a valid pattern or patterns.*
21+
22+
## Example
23+
24+
*Provide an example of better modeling*

graph/patterns/viewpoint.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Viewpoint
2+
3+
Microsoft Graph API Design Pattern
4+
5+
6+
*The viewpoint pattern provides the ability to manage properties of a shared object that have different values for different users.*
7+
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.
10+
## Solution
11+
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 `viewpoint` structural properties represent type specific user context across different M365 services and features.
15+
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 additional complexity to the client. To support queries for a user state the `viewpoint` property should support filtering.
17+
## Issues and considerations
18+
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">
23+
<Annotation Term="Org.OData.Core.V1.Computed" Bool="true" />
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.
27+
- Often, updating the `viewpoint` property may cause a side effect, so you might consider an OData action to do the update. For some user scenarios, the `PATCH` method could be a better way to update a `viewpoint`.
28+
29+
## Examples
30+
31+
### Defining a viewpoint
32+
33+
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:
34+
```
35+
<ComplexType Name="chatViewpoint" >
36+
<Property Name="isHidden" Type="Edm.Boolean" />
37+
<Property Name="lastMessageReadDateTime" Type="Edm.DateTimeOffset" />
38+
</ComplexType>
39+
40+
<EntityType Name="chat" BaseType="graph.entity" >
41+
<Property Name="chatType" Type="graph.chatType" Nullable="false" />
42+
<Property Name="createdDateTime" Type="Edm.DateTimeOffset" />
43+
<Property Name="lastUpdatedDateTime" Type="Edm.DateTimeOffset" />
44+
<Property Name="topic" Type="Edm.String" />
45+
<Property Name="viewpoint" Type="graph.chatViewpoint" />
46+
...
47+
<NavigationProperty Name="tabs" Type="Collection(graph.teamsTab)" ContainsTarget="true" />
48+
</EntityType>
49+
50+
```
51+
### Reading an entity with a viewpoint
52+
53+
The following example shows reading a collection of chats for an identified user, with a viewpoint for each chat:
54+
55+
```http
56+
GET https://graph.microsoft.com/v1.0/users/8b081ef6-4792-4def-b2c9-c363a1bf41d5/chats
57+
```
58+
59+
```http
60+
HTTP/1.1 200 OK
61+
Content-type: application/json
62+
63+
{
64+
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#chats",
65+
"@odata.count": 3,
66+
"value": [
67+
{
68+
"id": "19:meeting_MjdhNjM4YzUtYzExZi00OTFkLTkzZTAtNTVlNmZmMDhkNGU2@thread.v2",
69+
"topic": "Meeting chat sample",
70+
"createdDateTime": "2020-12-08T23:53:05.801Z",
71+
"lastUpdatedDateTime": "2022-12-08T23:58:32.511Z",
72+
"chatType": "meeting",
73+
"viewpoint":{
74+
"lastMessageReadDateTime": "2021-03-28T21:10:00.000Z"
75+
}
76+
},
77+
{
78+
"id": "19:[email protected]",
79+
"topic": "Group chat sample",
80+
"createdDateTime": "2020-12-03T19:41:07.054Z",
81+
"lastUpdatedDateTime": "2020-12-08T23:53:11.012Z",
82+
"chatType": "group",
83+
"viewpoint":{
84+
"lastMessageReadDateTime": "0000-01-01T00:00:00.000Z"
85+
}
86+
}
87+
]
88+
}
89+
```
90+
### Updating a viewpoint using an action
91+
92+
The following example shows marking a chat `viewpoint` as read for a user using an action:
93+
94+
```http
95+
96+
POST https://graph.microsoft.com/beta/chats/19:7d898072-792c-4006-bb10-5ca9f2590649_8ea0e38b-efb3-4757-924a-5f94061cf8c2@unq.gbl.spaces/markChatReadForUser
97+
Content-Type: application/json
98+
Content-length: 106
99+
100+
{
101+
"user": {
102+
"id" : "d864e79f-a516-4d0f-9fee-0eeb4d61fdc2",
103+
"tenantId": "2a690434-97d9-4eed-83a6-f5f13600199a"
104+
}
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+
```
113+
### Updating a viewpoint using `PATCH` method
114+
115+
The following example shows how to mark a topic with the `viewpoint` label as reviewed for a user by using the `PATCH` method (this example does not represent an actual API, but only an illustration):
116+
117+
```
118+
PATCH https://graph.microsoft.com/beta/sampleTopics/19:7d898072-792c-4006-bb10-5ca9f259
119+
120+
HTTP/1.1 200 OK
121+
Content-Type: application/json
122+
123+
{
124+
"title": "Announcements: Changes to PowerPoint and Word to open files faster",
125+
...
126+
"viewpoint": {
127+
"isReviewed" : "true"
128+
}
129+
}
130+
```
131+
132+
The server responds with a success status code and no payload:
133+
134+
```http
135+
HTTP/1.1 204 No Content
136+
```

0 commit comments

Comments
 (0)