Skip to content

Commit 16d3eca

Browse files
authored
Merge branch 'vNext' into dkershaw10-idempotentOperations
2 parents 228225f + dd41040 commit 16d3eca

File tree

10 files changed

+399
-57
lines changed

10 files changed

+399
-57
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

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
> # NOTICE TO READERS
2-
>
3-
> ## Guidance for Azure service teams
4-
> Azure service teams should use companion documents, [Azure REST API Guidelines](./azure/Guidelines.md) and [Considerations for Service Design](./azure/ConsiderationsForServiceDesign.md), when building or modifying their services. These documents provide a refined set of guidance targeted specifically for Azure services. For more information please refer to the [README](./azure/README.md) in the Azure folder.
5-
>
6-
> ## Guidance for Microsoft Graph service teams
7-
> Microsoft Graph service teams should reference the companion document, [Graph REST API Guidelines](./graph/GuidelinesGraph.md) when building or modifying their services.
8-
>
9-
> In the process of building many of Microsoft's highest scale services, the Microsoft Graph team found the Microsoft API guidelines tremendously useful as a baseline. However, there are several areas where we need to provide more clarity on how developers should describe their APIs. The companion document, [Graph REST API Guidelines](./graph/GuidelinesGraph.md) is a set of amendments and clarifications for Microsoft Graph that act as further reading. Recognizing that two documents is a lot for a new API designer to absorb, our plan is to follow the approach Azure have taken and roll out guidelines for Microsoft Graph into a single consolidated document.
1+
# NOTICE TO READERS
2+
3+
## Guidance for Azure service teams
4+
Azure service teams should use companion documents, [Azure REST API Guidelines](./azure/Guidelines.md) and [Considerations for Service Design](./azure/ConsiderationsForServiceDesign.md), when building or modifying their services. These documents provide a refined set of guidance targeted specifically for Azure services. For more information please refer to the [README](./azure/README.md) in the Azure folder.
5+
6+
## Guidance for Microsoft Graph service teams
7+
Microsoft Graph service teams should reference the companion document, [Graph REST API Guidelines](./graph/GuidelinesGraph.md) when building or modifying their services.
8+
9+
In the process of building many of Microsoft's highest scale services, the Microsoft Graph team found the Microsoft API guidelines tremendously useful as a baseline. However, there are several areas where we need to provide more clarity on how developers should describe their APIs. The companion document, [Graph REST API Guidelines](./graph/GuidelinesGraph.md) is a set of amendments and clarifications for Microsoft Graph that act as further reading. Recognizing that two documents is a lot for a new API designer to absorb, our plan is to follow the approach Azure have taken and roll out guidelines for Microsoft Graph into a single consolidated document.
1010

1111
---
1212

azure/ConsiderationsForServiceDesign.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,7 @@ This header is targeted at developers or operation professionals, and it is inte
180180
A major inhibitor to adoption and usage is when an API behaves in an unexpected way. Often, these are subtle design decisions that seem benign at the time, but end up introducing significant downstream friction for developers.
181181

182182
One common area of friction for developers is _polymorphism_ -- where a value may have any of several types or structures.
183-
Polymorphism can be beneficial in certain cases, e.g. as a way to express inheritance, but also creates friction
184-
because it requires the value to be introspected before being processed and cannot be represented in a natural/useful way in many type-safe languages.
185-
186-
:ballot_box_with_check: **YOU SHOULD** avoid polymorphism, especially in the response. An endpoint **YOU SHOULD** work with a single type to avoid problems during SDK creation.
187-
188-
:ballot_box_with_check: **YOU SHOULD** return a homogeneous collection (single type). Do not return heterogeneous collections unless there is a really good reason to do so. If you feel heterogeneous collections are required, discuss the requirement with an API reviewer prior to implementation.
183+
Polymorphism can be beneficial in certain cases, e.g. as a way to express inheritance, but also creates friction because it requires the value to be introspected before being processed and cannot be represented in a natural/useful way in many nominally typed languages. The use of a discriminator field (`kind`) simplifies the introspection, but developers frequently end up having to explicitly cast the response to the appropriate type in order to use it.
189184

190185
Collections are another common area of friction for developers. It is important to define collections in a consistent manner within your service and across services of the platform. In particular, features such as pagination, filtering, and sorting, when supported, should follow common API patterns. See [Collections](./Guidelines.md#collections) for specific guidance.
191186

azure/Guidelines.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,13 +430,14 @@ This indicates to client libraries and customers that values of the enumeration
430430

431431
#### Polymorphic types
432432

433-
<a href="#json-avoid-polymorphism" name="json-avoid-polymorphism">:warning:</a> **YOU SHOULD NOT** use polymorphic JSON types because they greatly complicate the customer code due to runtime dynamic casts and the introduction of new types in the future.
433+
Polymorphism types in REST APIs refers to the possibility to use the same property of a request or response to have similar but different shapes. This is commonly expressed as a `oneOf` in JsonSchema or OpenAPI. In order to simplify how to determine which specific type a given request or response payload corresponds to, Azure requires the use of an explicit discriminator field.
434434

435-
If you can't avoid them, then follow the guideline below.
435+
Note: Polymorphic types can make your service more difficult for nominally typed languages to consume. See the corresponding section in the [Considerations for service design](./ConsiderationsForServiceDesign.md#avoid-surprises) for more information.
436436

437437
<a href="#json-use-discriminator-for-polymorphism" name="json-use-discriminator-for-polymorphism">:white_check_mark:</a> **DO** define a discriminator field indicating the kind of the resource and include any kind-specific fields in the body.
438438

439439
Below is an example of JSON for a Rectangle and Circle with a discriminator field named `kind`:
440+
440441
**Rectangle**
441442
```json
442443
{

graph/GuidelinesGraph.md

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,26 @@
33
Table of contents
44

55
- [Microsoft Graph REST API Guidelines](#microsoft-graph-rest-api-guidelines)
6-
- [](#)
7-
- [History](#history)
86
- [Introduction](#introduction)
97
- [Legend](#legend)
108
- [Design approach](#design-approach)
119
- [Naming](#naming)
1210
- [Uniform Resource Locators (URLs)](#uniform-resource-locators-urls)
13-
- [Query support](#query-support)
1411
- [Resource modeling patterns](#resource-modeling-patterns)
1512
- [Pros and cons](#pros-and-cons)
13+
- [Query support](#query-support)
1614
- [Behavior modeling](#behavior-modeling)
1715
- [Error handling](#error-handling)
16+
- [Enums](#enums)
1817
- [API contract and non-backward compatible changes](#api-contract-and-non-backward-compatible-changes)
1918
- [Versioning and deprecation](#versioning-and-deprecation)
2019
- [Recommended API design patterns](#recommended-api-design-patterns)
2120
- [References](#references)
2221

23-
##
24-
25-
#### History
26-
27-
| Date | Notes |
28-
|-------------|-----------------------------|
29-
| 2022-Jun-14 | Edit pass for formatting, links |
30-
| 2021-Sep-28 | Using summary and patterns style |
31-
| 2020-Oct-04 | Initial version in Wiki |
3222

3323
## Introduction
3424

35-
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.
3626

3727
This document offers guidance that Microsoft Graph API producer teams MUST follow to
3828
ensure that Microsoft Graph has a consistent and easy-to-use API surface. A new API design should meet the following goals:
@@ -125,6 +115,7 @@ Following is a short summary of the most often used conventions.
125115
| :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 |
126116
| :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) |
127117
| :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 |
128119

129120
### Uniform Resource Locators (URLs)
130121

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

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

162-
### Query support
163-
164-
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).
165-
166-
|Requirements |
167-
|----------------------------------------------------------------------------------------------------|
168-
| :heavy_check_mark: **MUST** support `$select on resource` to enable properties projection. |
169-
| :ballot_box_with_check: **SHOULD** support `/entityTypeCollection/{id}?$expand=navProp1` option for navigation properties of entities. |
170-
| :ballot_box_with_check: **SHOULD** support `$filter` with `eq` and `ne` operations on properties of entity collections. |
171-
| :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). |
172-
| :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`). |
173-
| :ballot_box_with_check: **SHOULD** support `$count` for collections. |
174-
| :ballot_box_with_check: **SHOULD** support sorting with `$orderby` both ascending and descending on properties of the entities. |
175-
176-
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
177-
[OData Query Options](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_PassingQueryOptionsintheRequestBody).
178-
179-
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).
180-
181153
### Resource modeling patterns
182154

183155
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.
@@ -219,6 +191,8 @@ The three most often used patterns in Microsoft Graph today are type hierarchy,
219191

220192
- **[Flat bag of properties](./patterns/flat-bag.md)** is represented by one entity type with all the potential properties plus an additional property to distinguish the variants, often called type. The type property describes the variant and also defines properties that are required or meaningful for the variant given by the type property.
221193

194+
- **[Enums](./patterns/enums.md)** represent a subset of the nominal type they rely on, and are especially useful in cases where certain properties have predefined, limited options.
195+
222196
The following table shows a summary of the main qualities for each pattern and can help you select a pattern fit for your use case.
223197

224198
| API qualities\patterns | Properties and behavior described in metadata | Supports combinations of properties and behaviors | Simple query construction |
@@ -248,6 +222,26 @@ Following are a few pros and cons to decide which pattern to use:
248222
> **Note:**
249223
> 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.
250224
225+
### Query support
226+
227+
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).
228+
229+
|Requirements |
230+
|----------------------------------------------------------------------------------------------------|
231+
| :heavy_check_mark: **MUST** support `$select on resource` to enable properties projection. |
232+
| :ballot_box_with_check: **SHOULD** support `/entityTypeCollection/{id}?$expand=navProp1` option for navigation properties of entities. |
233+
| :ballot_box_with_check: **SHOULD** support `$filter` with `eq` and `ne` operations on properties of entity collections. |
234+
| :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). |
235+
| :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`). |
236+
| :ballot_box_with_check: **SHOULD** support `$count` for collections. |
237+
| :ballot_box_with_check: **SHOULD** support sorting with `$orderby` both ascending and descending on properties of the entities. |
238+
239+
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
240+
[OData Query Options](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_PassingQueryOptionsintheRequestBody).
241+
242+
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).
243+
244+
251245
### Behavior modeling
252246

253247
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.
@@ -268,6 +262,7 @@ Operation resources must have a binding parameter that matches the type of the b
268262

269263
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).
270264

265+
271266
### Error handling
272267

273268
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:
@@ -391,6 +386,7 @@ The guidelines in previous sections are intentionally brief and provide a jump s
391386
| [Operations](./patterns/operations.md) | Model complex business operations |
392387
| [Type hierarchy](./patterns/subtypes.md) | Model `is-a` relationships using subtypes. |
393388
| [Upsert](./patterns/upsert.md) | Idempotent operation to create or update a resource using a client-provided key. |
389+
| [Viewpoint](./patterns/viewpoint.md) | Model user specific properties for a shared resource. |
394390

395391
## References
396392

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*

0 commit comments

Comments
 (0)