Skip to content

Commit 344664c

Browse files
committed
- adds dictionary usage guidelines for graph
1 parent 5cc80bd commit 344664c

File tree

2 files changed

+264
-0
lines changed

2 files changed

+264
-0
lines changed

graph/dictionary/client-guidance.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Dictionary types
2+
3+
The client guidance is a collection of additional information provided to SDK implementers and client applications. This information is meant to help understand how various guidelines and concept translate in their world and clarify a few unknowns. You should always read the corresponding guideline first to get a context understanding.
4+
5+
[Read the guideline](./index.md).
6+
7+
## OpenAPI example
8+
9+
The following json-schema/OpenAPI example defines a dictionary of which values will by of type **RoleSettings**.
10+
11+
In **components** in **schemas**:
12+
13+
```json
14+
{
15+
"roleSettings": {
16+
"type": "object",
17+
"properties": {
18+
"domain": {
19+
"type": "string"
20+
}
21+
}
22+
}
23+
}
24+
}
25+
```
26+
27+
```json
28+
{
29+
"type": "object",
30+
"patternProperties": {
31+
".*": {
32+
"$ref": "#/components/schemas/roleSettings"
33+
},
34+
"additionalProperties": false
35+
}
36+
}
37+
```
38+
39+
## SDK Support
40+
41+
SDKs need to provide support for dictionary types so SDK consummers get a delightful development experience. Examples are provided below for different languages. Other aspects need to be taken into considerations:
42+
43+
- Dictionaries support OData annotations (values prefixed with **@OData**), such annotations should not be inserted directly in the dictionary but rather in the additional properties manager.
44+
- Dictionary types can inherit another dictionary type, this inheritance must be respected.
45+
- Dictionary values can be of union types, if the target langauge doesn't support union types, a wrapper type should be generated as backward compatible solution with properties for each type of the union.
46+
47+
### Dotnet
48+
49+
```CSharp
50+
Dictionary<string, RoleSettings>
51+
```
52+
53+
### Java
54+
55+
```Java
56+
Map<string, RoleSettings>
57+
```
58+
59+
### JavaScript/TypeScript
60+
61+
```TypeScript
62+
Map<string, RoleSettings>
63+
```
64+
65+
or
66+
67+
```JavaScript
68+
{
69+
[key: string]: {value: RoleSettings}
70+
}
71+
```
72+
73+
## Request builder generation annotation
74+
75+
By default SDKs are not required to contain a set of request builders to run CRUD requests on entries in the dictionary. The dictionary will be updated as a whole by consummers by sending requests to the parent entity.
76+
77+
If a **SupportedHttpMethod** annotation is specified for the dictionary type, request builders should be generated to allow consummers to automically update the entries.

graph/dictionary/index.md

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
# Dictionary types
2+
3+
Dictionaries, sometimes called maps, are a collection of name-value pairs. They allow dynamic data sets to be accessed in a systematic manner and are a good compromise between a strictly defined ahead of time structure with all its named properties and between a loosely defined dynamic object (i.e. OData OpenTypes).
4+
5+
More information:
6+
7+
- [OData reference](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md#dictionary)
8+
9+
## When to use dictionary types
10+
11+
Before using a dictionary type in your API definition make sure your scenario fits the following criteria:
12+
13+
- The data values MUST be related to one another semantically as a collection.
14+
- The value types MUST be a primitive type or is a **ComplexType**. Mixed primitive types are not allowed.
15+
- The client MUST define the keys of this type. As opposed to the service defining it in advance.
16+
17+
### Alternatives to consider
18+
19+
- [Open extensions](https://docs.microsoft.com/en-us/graph/extensibility-open-users) when you want to provide clients the ability to extend Microsoft Graph.
20+
- [Open types](https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/use-open-types-in-odata-v4) when your data is not a collection in nature.
21+
- [Complex types](https://docs.microsoft.com/en-us/odata/webapi/complextypewithnavigationproperty) when the set of data values are known.
22+
23+
## JSON payload example
24+
25+
The following example illustrates the resulting JSON for a property of dictionary type. The parent object has been ommitted for brievety.
26+
27+
```json
28+
{
29+
"author": {
30+
"domain": "contoso"
31+
},
32+
"maintainer": {
33+
"domain": "fabrikam"
34+
},
35+
"architect": {
36+
"domain": "adventureWorks"
37+
}
38+
}
39+
```
40+
41+
## HTTP calls examples
42+
43+
In this set of examples we're modeling a **roles** property of dictionary type on the user entity which is exposed by the users entity set.
44+
45+
### Getting an entry from the dictionary
46+
47+
```HTTP
48+
GET https://graph.microsoft.com/v1.0/users/10/roles/author
49+
```
50+
51+
Reponse:
52+
53+
```json
54+
{
55+
"domain": "contoso"
56+
}
57+
```
58+
59+
### Getting the dictionary
60+
61+
```HTTP
62+
GET https://graph.microsoft.com/v1.0/users/10/roles
63+
```
64+
65+
Reponse:
66+
67+
```json
68+
{
69+
"author": {
70+
"domain": "contoso"
71+
},
72+
"maintainer": {
73+
"domain": "fabrikam"
74+
},
75+
"architect": {
76+
"domain": "adventureWorks"
77+
}
78+
}
79+
```
80+
81+
### Getting the entity with the dictionary
82+
83+
```HTTP
84+
GET https://graph.microsoft.com/v1.0/users/10
85+
```
86+
87+
Reponse:
88+
89+
```json
90+
{
91+
"id": "10",
92+
"displayName": "Jane Smith",
93+
"roles": {
94+
"author": {
95+
"domain": "contoso"
96+
},
97+
"maintainer": {
98+
"domain": "fabrikam"
99+
},
100+
"architect": {
101+
"domain": "adventureWorks"
102+
}
103+
}
104+
}
105+
```
106+
107+
### Creating an entry in the dictionary
108+
109+
```HTTP
110+
POST https://graph.microsoft.com/v1.0/users/10/roles/author
111+
112+
{
113+
"domain": "contoso"
114+
}
115+
```
116+
117+
### Updating the dictionary
118+
119+
```HTTP
120+
PATCH https://graph.microsoft.com/v1.0/users/10/roles
121+
122+
{
123+
"author": {
124+
"domain": "contoso1"
125+
},
126+
"maintainer": {
127+
"domain": "fabrikam1"
128+
},
129+
"reviewer": {
130+
"domain": "fabrikam"
131+
},
132+
"architect": null
133+
}
134+
```
135+
136+
> Note: setting one of the keys to **null** deletes it from the dictionary.
137+
> Note: the domain values for the existing author and maintainer entries will get udpated.
138+
> Note: the reviewer entry will be inserted in the dictionary.
139+
140+
### Updating an entry in the dictionary
141+
142+
```HTTP
143+
PATCH https://graph.microsoft.com/v1.0/users/10/roles/author
144+
145+
{
146+
"domain": "fabrikam"
147+
}
148+
```
149+
150+
### Deleting an entry from the dictionary
151+
152+
```HTTP
153+
DELETE https://graph.microsoft.com/v1.0/users/10/roles/author
154+
```
155+
156+
## CDSL example
157+
158+
The following example defines a complex type **roleSettings** as well as a dictionary of which the key will be a string and the value a **roleSettings**.
159+
160+
```xml
161+
<ComplexType Name="roleSettings">
162+
<Property Name ="domain" Type="Edm.String" Nullable="false" />
163+
</ComplexType>
164+
165+
<ComplexType Name="assignedRoleGroupDictionary" BaseType="Org.OData.Core.V1.Dictionary">
166+
<!-- Note: Strongly-typed dictionary
167+
of roleSettings
168+
keyed by name of roleGroup. -->
169+
<Annotation Term="Org.OData.Validation.V1.OpenPropertyTypeConstraint">
170+
<Collection>
171+
<String>microsoft.graph.roleSettings</String>
172+
</Collection>
173+
</Annotation>
174+
<Annotation Term="SupportedHttpMethod">
175+
<Collection><!-- use this annotation to indicate you want the SDKs to generate additional request builders to update the dictionary atomtically -->
176+
<String>GET</String>
177+
<String>PATCH</String>
178+
<String>DELETE</String>
179+
<String>POST</String>
180+
<Collection>
181+
</Annotation>
182+
</ComplexType>
183+
```
184+
185+
## Additional information
186+
187+
[SDK implementation guidance](./client-guidance.md).

0 commit comments

Comments
 (0)