Skip to content

Commit e35e691

Browse files
authored
move to different file
1 parent ad75cfb commit e35e691

File tree

3 files changed

+133
-129
lines changed

3 files changed

+133
-129
lines changed

graph/GuidelinesGraph.md

Lines changed: 3 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ The three most often used patterns in Microsoft Graph today are type hierarchy,
191191

192192
- **[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.
193193

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+
196+
194197
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.
195198

196199
| API qualities\patterns | Properties and behavior described in metadata | Supports combinations of properties and behaviors | Simple query construction |
@@ -319,135 +322,7 @@ For a complete mapping of error codes to HTTP statuses, see
319322

320323
<a name="api-contract-and-non-backward-compatible-changes"></a>
321324

322-
### Enums
323-
324-
In OData, enums represent a subset of the nominal type they rely on, and are especially useful in cases where certain properties have predefined, limited options.
325-
326-
```xml
327-
<EnumType Name="Color">
328-
<Member Name="Red" Value="0" />
329-
<Member Name="Green" Value="1" />
330-
<Member Name="Blue" Value="2" />
331-
</EnumType>
332-
```
333-
334-
#### Pros
335-
336-
- Our SDK generators will translate the enum to the best representation of the target programming language, resulting in a better developer experience and free client side validation
337-
338-
#### Cons
339-
340-
- Adding a new value requires to go through a (generally fast) API Review
341-
- If the enum is not [evolvable](./patterns/evolvable-enums.md), adding a new value is a breaking change and will generally not be allowed
342-
343-
#### Enum or Booleans
344-
345-
Enumerations are a good alternative to Booleans when one of the two values (`true`, `false`) conveys other possible values not yet conceived. Let's assume we have an `Error` type and a property to communicate how to display it:
346-
347-
```xml
348-
<ComplexType Name="Error">
349-
<Property Name="title" Type="Edm.String" />
350-
<Property Name="message" Type="Edm.String" />
351-
<Property Name="displayAsTip" Type="Edm.Boolean" />
352-
</ComplexType>
353-
```
354-
355-
The `false` value here merely communicates that the error shall not be displayed as a tip. What if, in the future, the error could be displayed as a `tip` or `alert`, and then in a more distant future, a `dialog` option is viable?
356-
357-
With the current model, the only way is to add more boolean properties to convey the new information:
358-
359-
```diff
360-
<ComplexType Name="Error">
361-
<Property Name="title" Type="Edm.String" />
362-
<Property Name="message" Type="Edm.String" />
363-
<Property Name="displayAsTip" Type="Edm.Boolean" />
364-
+ <Property Name="displayAsAlert" Type="Edm.Boolean" />
365-
+ <Property Name="displayAsDialog" Type="Edm.Boolean" />
366-
</ComplexType>
367-
```
368-
369-
Additionally speaking, the workload will now also have to validate the data structure and make sure that only one of the 3 values is `true`
370-
371-
By using an evolvable enum, instead, all we need to do is to add new members:
372-
373-
```diff
374-
<ComplexType Name="Error">
375-
<Property Name="title" Type="Edm.String" />
376-
<Property Name="message" Type="Edm.String" />
377-
+ <Property Name="displayMethod" Type="microsoft.graph.displayMethod" />
378-
- <Property Name="displayAsTip" Type="Edm.Boolean" />
379-
- <Property Name="displayAsAlert" Type="Edm.Boolean" />
380-
- <Property Name="displayAsDialog" Type="Edm.Boolean" />
381-
</ComplexType>
382-
```
383-
384-
```xml
385-
<EnumType Name="displayMethod">
386-
<Member Name="tip" Value="0" />
387-
<Member Name="unknownFutureValue" Value="1" />
388-
<Member Name="alert" Value="2" />
389-
<Member Name="dialog" Value="3" />
390-
</EnumType>
391-
```
392-
393-
Similarly speaking, if you find yourself using a `nullable` Enum, that is a indication that maybe what you are trying to model is something that has 3 states and an enum is more appropraite. For instance, let's assume we have a boolean property called `syncEnabled`, where `null` means that the value is undefined and inherited from the general tenant configuration. Instead of modelling like a boolean:
394-
395-
```xml
396-
<Property Name="syncEnabled" Type="Edm.Boolean" Nullable="true"/>
397-
```
398-
399-
An enum not only better conveys the message:
400-
401-
```xml
402-
<EnumType Name="syncState">
403-
<Member Name="enabled" Value="0" />
404-
<Member Name="disabled" Value="1" />
405-
<Member Name="tenantInherit" Value="2" />
406-
<Member Name="unknownFutureValue" Value="3" />
407-
</EnumType>
408-
```
409-
410-
but it is also open for future scenarios:
411-
412-
```diff
413-
<EnumType Name="syncState">
414-
<Member Name="enabled" Value="0" />
415-
<Member Name="disabled" Value="1" />
416-
<Member Name="tenantInherit" Value="2" />
417-
<Member Name="unknownFutureValue" Value="3" />
418-
+ <Member Name="groupInherit" Value="4" />
419-
</EnumType>
420-
```
421-
422-
Additionally speaking, depending on the situation, a nullable enum can very likely be avoided by adding a `none` member.
423-
424-
#### Flag Enums or Collection of Enums
425-
426-
In case an enum can have multiple values at the same time the tentation is to model the property as a collection of Enums:
427-
428-
```xml
429-
<Property Name="displayMethods" Type="Collection(displayMethod)"/>
430-
```
431-
432-
However, [Flagged Enums](https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#_Toc38530378) can model this use case scenario:
433-
434-
```diff
435-
- <EnumType Name="displayMethod">
436-
+ <EnumType Name="displayMethod" isFlag="true">
437-
- <Member Name="tip" Value="0" />
438-
+ <Member Name="tip" Value="1" />
439-
- <Member Name="unknownFutureValue" Value="1" />
440-
+ <Member Name="unknownFutureValue" Value="2" />
441-
- <Member Name="alert" Value="2" />
442-
+ <Member Name="alert" Value="4" />
443-
- <Member Name="dialog" Value="3" />
444-
+ <Member Name="dialog" Value="8" />
445-
</EnumType>
446-
```
447-
448-
With such enum, customers can select multiple values in a single field:
449325

450-
`displayMethod = tip | alert`
451326

452327
## API contract and non-backward compatible changes
453328

graph/patterns/enums.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
### Enums
2+
3+
In OData, enums represent a subset of the nominal type they rely on, and are especially useful in cases where certain properties have predefined, limited options.
4+
5+
```xml
6+
<EnumType Name="Color">
7+
<Member Name="Red" Value="0" />
8+
<Member Name="Green" Value="1" />
9+
<Member Name="Blue" Value="2" />
10+
</EnumType>
11+
```
12+
13+
#### Pros
14+
15+
- Our SDK generators will translate the enum to the best representation of the target programming language, resulting in a better developer experience and free client side validation
16+
17+
#### Cons
18+
19+
- Adding a new value requires to go through a (generally fast) API Review
20+
- If the enum is not [evolvable](./patterns/evolvable-enums.md), adding a new value is a breaking change and will generally not be allowed
21+
22+
#### Enum or Booleans
23+
24+
Enumerations are a good alternative to Booleans when one of the two values (`true`, `false`) conveys other possible values not yet conceived. Let's assume we have an `Error` type and a property to communicate how to display it:
25+
26+
```xml
27+
<ComplexType Name="Error">
28+
<Property Name="title" Type="Edm.String" />
29+
<Property Name="message" Type="Edm.String" />
30+
<Property Name="displayAsTip" Type="Edm.Boolean" />
31+
</ComplexType>
32+
```
33+
34+
The `false` value here merely communicates that the error shall not be displayed as a tip. What if, in the future, the error could be displayed as a `tip` or `alert`, and then in a more distant future, a `dialog` option is viable?
35+
36+
With the current model, the only way is to add more boolean properties to convey the new information:
37+
38+
```diff
39+
<ComplexType Name="Error">
40+
<Property Name="title" Type="Edm.String" />
41+
<Property Name="message" Type="Edm.String" />
42+
<Property Name="displayAsTip" Type="Edm.Boolean" />
43+
+ <Property Name="displayAsAlert" Type="Edm.Boolean" />
44+
+ <Property Name="displayAsDialog" Type="Edm.Boolean" />
45+
</ComplexType>
46+
```
47+
48+
Additionally speaking, the workload will now also have to validate the data structure and make sure that only one of the 3 values is `true`
49+
50+
By using an evolvable enum, instead, all we need to do is to add new members:
51+
52+
```diff
53+
<ComplexType Name="Error">
54+
<Property Name="title" Type="Edm.String" />
55+
<Property Name="message" Type="Edm.String" />
56+
+ <Property Name="displayMethod" Type="microsoft.graph.displayMethod" />
57+
- <Property Name="displayAsTip" Type="Edm.Boolean" />
58+
- <Property Name="displayAsAlert" Type="Edm.Boolean" />
59+
- <Property Name="displayAsDialog" Type="Edm.Boolean" />
60+
</ComplexType>
61+
```
62+
63+
```xml
64+
<EnumType Name="displayMethod">
65+
<Member Name="tip" Value="0" />
66+
<Member Name="unknownFutureValue" Value="1" />
67+
<Member Name="alert" Value="2" />
68+
<Member Name="dialog" Value="3" />
69+
</EnumType>
70+
```
71+
72+
Similarly speaking, if you find yourself using a `nullable` Enum, that is a indication that maybe what you are trying to model is something that has 3 states and an enum is more appropraite. For instance, let's assume we have a boolean property called `syncEnabled`, where `null` means that the value is undefined and inherited from the general tenant configuration. Instead of modelling like a boolean:
73+
74+
```xml
75+
<Property Name="syncEnabled" Type="Edm.Boolean" Nullable="true"/>
76+
```
77+
78+
An enum not only better conveys the message:
79+
80+
```xml
81+
<EnumType Name="syncState">
82+
<Member Name="enabled" Value="0" />
83+
<Member Name="disabled" Value="1" />
84+
<Member Name="tenantInherit" Value="2" />
85+
<Member Name="unknownFutureValue" Value="3" />
86+
</EnumType>
87+
```
88+
89+
but it is also open for future scenarios:
90+
91+
```diff
92+
<EnumType Name="syncState">
93+
<Member Name="enabled" Value="0" />
94+
<Member Name="disabled" Value="1" />
95+
<Member Name="tenantInherit" Value="2" />
96+
<Member Name="unknownFutureValue" Value="3" />
97+
+ <Member Name="groupInherit" Value="4" />
98+
</EnumType>
99+
```
100+
101+
Additionally speaking, depending on the situation, a nullable enum can very likely be avoided by adding a `none` member.
102+
103+
#### Flag Enums or Collection of Enums
104+
105+
In case an enum can have multiple values at the same time the tentation is to model the property as a collection of Enums:
106+
107+
```xml
108+
<Property Name="displayMethods" Type="Collection(displayMethod)"/>
109+
```
110+
111+
However, [Flagged Enums](https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#_Toc38530378) can model this use case scenario:
112+
113+
```diff
114+
- <EnumType Name="displayMethod">
115+
+ <EnumType Name="displayMethod" isFlag="true">
116+
- <Member Name="tip" Value="0" />
117+
+ <Member Name="tip" Value="1" />
118+
- <Member Name="unknownFutureValue" Value="1" />
119+
+ <Member Name="unknownFutureValue" Value="2" />
120+
- <Member Name="alert" Value="2" />
121+
+ <Member Name="alert" Value="4" />
122+
- <Member Name="dialog" Value="3" />
123+
+ <Member Name="dialog" Value="8" />
124+
</EnumType>
125+
```
126+
127+
With such enum, customers can select multiple values in a single field:
128+
129+
`displayMethod = tip | alert`

graph/patterns/evolvable-enums.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Microsoft Graph API Design Pattern
44

55
*The evolvable enums pattern allows API producers to extend enumerated types with new members without breaking API consumers.*
66

7-
Note: You might be interested in reading the [Enum guidance](../GuidelinesGraph.md#enums) first
7+
Note: You might be interested in reading the [Enum guidance](./enums.md) first
88

99
## Problem
1010

0 commit comments

Comments
 (0)