You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
26
26
27
27
This document offers guidance that Microsoft Graph API producer teams MUST follow to
28
28
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.
115
115
|: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 |
116
116
|: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) |
117
117
|:no_entry:**MUST NOT** use collection, response, or request suffixes. | - **Right:** addresses <BR> - **Wrong:** addressCollection |
@@ -149,25 +150,6 @@ In Microsoft Graph, a top-level API category might represent one of the followin
149
150
150
151
Effectively, top-level categories define a perimeter for the API surface; thus, a new category creation requires additional rigor and governance approval.
151
152
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).
|: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
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
-
171
153
### Resource modeling patterns
172
154
173
155
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:
238
220
> **Note:**
239
221
> 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.
240
222
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).
|: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
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
+
241
243
### Behavior modeling
242
244
243
245
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
257
259
258
260
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).
259
261
262
+
260
263
### Error handling
261
264
262
265
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
508
511
|[Namespace](./patterns/namespace.md)| Organize resource definitions into a logical set. |
509
512
|[Navigation properties](./patterns/navigation-property.md)| Model resource relationships |
510
513
|[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.
*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.*
*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.
- 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:
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
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):
0 commit comments