Skip to content

Commit 543f87c

Browse files
committed
Create subsets.md
Moved *Modeling collection subsets* content from wiki page to GitHub
1 parent b275173 commit 543f87c

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed

graph/patterns/subsets.md

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# Modeling collection subsets
2+
3+
Microsoft Graph API Design Pattern
4+
5+
The modeling collection subsets pattern is the modeling state associated to a collection that may include all instances, an included subset, an excluded subset, no instances, or any combinations of the preceding items.
6+
7+
A common pattern is to apply a policy or state to a collection of objects. With this, there also comes the question of how to model cases where we want to apply to 'all' or 'none' without having to special case these values within the collection set or introduce cross-property dependencies. Likewise, we'd like to model it in a way where it is easy to understand and interpret usage from just looking at the schema.
8+
9+
An example is where you have a policy that you need to be able to apply to users in an organization. You might want to support the default **None**, enablement for **All**, or enablement for **Select** users where you only grant it to a few users.
10+
11+
## Problem
12+
13+
--------
14+
15+
Existing patterns for this either have special-cased 'strings' or have tightly coupled dependencies between two independent properties. Neither is intuitive, both require reading documentation, and neither can be inferred from the schema or within client libraries.
16+
17+
## Solution
18+
19+
--------
20+
21+
Have an abstract base class where all 'variants' of the subset are derived types from the base subset. For more information, see the [general subtyping guidance](https://github.com/microsoft/api-guidelines/blob/graph/graph/patterns/subtypes.md).
22+
23+
The abstract base class should also hold an enum for all possible variants. The purpose of including this is to allow for easier ways to do query and filter operations on variants like 'all' and 'none' without relying on `isof` functions.
24+
25+
Base type
26+
27+
```xml
28+
<ComplexType Name="membership" IsAbstract="true">
29+
<Property Name="membershipKind" Type="graph.membershipKind"/>
30+
</ComplexType>
31+
32+
<Enum Name="membershipKind">
33+
<Member Name="all"/>
34+
<Member Name="enumerated"/>
35+
<Member Name="none"/>
36+
<Member Name="unknownFutureValue"/>
37+
</Enum>
38+
```
39+
40+
Derived types
41+
42+
```xml
43+
<ComplexType Name="noMembership" BaseType="graph.membership"/>
44+
45+
<ComplexType Name="allMembership" BaseType="graph.membership"/>
46+
47+
<ComplexType Name="enumeratedMembership" BaseType = "graph.membership">
48+
<Property Name="members" Type="Collection(Edm.String)"/>
49+
</ComplexType>
50+
51+
<ComplexType Name="excludedMembership" BaseType="graph.membership">
52+
<Property Name="members" Type="Collection(Edm.String)"/>
53+
</ComplexType>
54+
```
55+
56+
Be aware that the name values and types in the preceding examples are just examples and can be replaced with your scenario equivalent values. For example, types don't really need to be memberships. The collection doesn't have to be a collection at all; it can be singular and doesn't have to be a string.
57+
58+
```xml
59+
<ComplexType Name="<base-type>" IsAbstract="true">
60+
<Property Name="<enum-name-for-type>" Type="graph.<enum-type>"/>
61+
</ComplexType>
62+
63+
<Enum Name="<enum-type>">
64+
<Member Name="<value>"/>
65+
<Member Name="<value2>"/>
66+
<Member Name="unknownFutureValue"/>
67+
</Enum>
68+
69+
<ComplexType Name="<type-1>" BaseType="graph.<base-type>"/>
70+
71+
<ComplexType Name="<type-2>" BaseType="graph.<base-time>">
72+
<Property Name="<property-name>" Type="<property-type>"/>
73+
</ComplexType>
74+
```
75+
76+
## When to use this pattern
77+
78+
--------
79+
80+
Use this pattern when supporting two or more collection states of the following, where at least one of the states is a subset variant:
81+
82+
- All targets
83+
- No targets
84+
- Subset of targets to be included
85+
- Subset of targets to be excluded
86+
87+
If you only ever need to support two states&mdash;All or None&mdash;without using any subsets, it would be better to use a Boolean to toggle on and off.
88+
89+
## Issues and considerations
90+
91+
--------
92+
93+
Given that we are using an overarching subtype model, subtyping model limitations apply here as well; for more details, see the [subtyping documentation](https://github.com/microsoft/api-guidelines/blob/graph/graph/Modelling%20with%20Subtypes%20Pattern.md).
94+
95+
## Example
96+
97+
--------
98+
99+
GET https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies/
100+
101+
_Note: unrelated properties on entities are omitted for easier readability_
102+
103+
```json
104+
{
105+
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#conditionalAccessPolicy",
106+
"values": [
107+
{
108+
"id": "66d36273-fe4c-d478-dc22-e0179d856ce7",
109+
"conditions": {
110+
"users": {
111+
"includeGuestsOrExternalUsers": {
112+
"externalTenants": {
113+
"@odata.type":"microsoft.graph.conditionalAccessAllExternalTenants",
114+
"membershipKind": "all"
115+
}
116+
}
117+
}
118+
}
119+
},
120+
{
121+
"id": "99d212f4-d94e-cde1-8e3c-208d78238277",
122+
"conditions": {
123+
"users": {
124+
"includeGuestsOrExternalUsers": {
125+
"externalTenants": {
126+
"@odata.type":"microsoft.graph.conditionalAccessEnumeratedExternalTenants",
127+
"membershipKind": "enumerated",
128+
"members": ["bd005e2a-876d-4bf0-92a1-ae9ff4276d54"]
129+
}
130+
}
131+
}
132+
}
133+
}
134+
]
135+
}
136+
```
137+
138+
POST https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies/
139+
140+
_Note: unrelated properties on entities are omitted for easier readability_
141+
142+
```json
143+
{
144+
"id": "66d36273-fe4c-d478-dc22-e0179d856ce7",
145+
"conditions": {
146+
"users": {
147+
"includeGuestsOrExternalUsers": {
148+
"externalTenants": {
149+
"@odata.type":"microsoft.graph.conditionalAccessAllExternalTenants"
150+
}
151+
}
152+
}
153+
}
154+
}
155+
```
156+
157+
or
158+
159+
POST https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies/
160+
161+
_Note: unrelated properties on entities are omitted for easier readability_
162+
163+
```json
164+
{
165+
"id": "66d36273-fe4c-d478-dc22-e0179d856ce7",
166+
"conditions": {
167+
"users": {
168+
"includeGuestsOrExternalUsers": {
169+
"externalTenants": {
170+
"@odata.type":"microsoft.graph.conditionalAccessEnumeratedExternalTenants",
171+
"members": ["bd005e2a-876d-4bf0-92a1-ae9ff4276d54"]
172+
}
173+
}
174+
}
175+
}
176+
}
177+
```

0 commit comments

Comments
 (0)