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
*The dictionary type provides the ability to create a set of primitives or objects of the same type where the API consumer can define a name for each value in the set.*
5
+
_The dictionary type provides the ability to create a set key/value pairs where the set of keys is dynamically specified by the API consumer._
6
6
7
7
## Problem
8
8
9
-
The API design requires a resource to include an unknown quantity of data elements of the same type that must be named by using values provided by the API consumer.
9
+
The API design requires a resource to include an unknown quantity of data values whose keys are defined by the API consumer.
10
10
11
11
## Solution
12
12
13
-
API designers use a JSON object to represent a dictionary in an `application/json` response payload. When describing the model in CSDL, a new complex type can be created that derives from `Org.OData.Core.V1.Dictionary` and then uses the `Org.OData.Validation.V1.OpenPropertyTypeConstraint` to constrain the type that can be used for the values in the dictionary.
13
+
API designers use a JSON object to represent a dictionary in an `application/json` response payload. When describing the model in CSDL, a new complex type can be created that derives from `graph.Dictionary` and optionally uses the `Org.OData.Validation.V1.OpenPropertyTypeConstraint` to constrain the type that can be used for the values in the dictionary as appropriate.
14
14
15
-
Dictionary entries can be added via `POST`, updated via `PATCH`, and removed by setting the entry value to `null`. Multiple entries can be updated at the same time by using `PATCH` on the dictionary property.
15
+
Dictionary entries can be added, removed, or modified via `PATCH` to the dictionary property. Entries are removed by setting the property to `null`.
16
16
17
17
## When to use this pattern
18
18
19
19
Before using a dictionary type in your API definition, make sure that your scenario fits the following criteria:
20
20
21
21
- The data values MUST be related to one another semantically as a collection.
22
-
- The value types MUST be a primitive type or a **ComplexType**. Mixed primitive types are not allowed.
22
+
- The values MUST be primitive or complex types.
23
23
- The client MUST define the keys of this type, as opposed to the service defining them in advance.
24
24
25
25
### Alternatives
@@ -31,58 +31,138 @@ Before using a dictionary type in your API definition, make sure that your scena
31
31
32
32
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 a loosely defined dynamic object (such as OData OpenTypes).
33
33
34
-
Because dictionary entries are removed by setting the value to `null`, dictionaries can only support values that are non-nullable.
35
-
36
-
Open questions:
37
-
38
-
- Can/should PUT be supported on the dictionary property and/or the entry value?
39
-
- What does OData say about being able to POST to a structured property? Will OData Web API allow that?
40
-
- Must an implementer support PATCH at both the dictionary level and the entry level?
34
+
Because dictionary entries are removed by setting the value to `null`, dictionaries don't support null values.
41
35
42
36
For more information, see the [OData reference](https://github.com/oasis-tcs/odata-vocabularies/blob/master/vocabularies/Org.OData.Core.V1.md#dictionary).
43
37
44
38
## Examples
45
39
46
-
### JSON payload example
40
+
### Declaring a string dictionary
41
+
The following example demonstrates defining a dictionary that can contain string values.
The following example illustrates the resulting JSON for a property of dictionary type. The parent object has been omitted for brevity.
63
+
### Reading a dictionary
64
+
Dictionaries are represented in JSON payloads as a JSON object, where the property names are comprised of the keys and their values are the corresponding key values.
49
65
66
+
The following example shows reading an item with a dictionary property named "userTags":
67
+
68
+
```HTTP
69
+
GET /item
70
+
```
71
+
Response:
50
72
```json
51
73
{
52
-
"author": {
53
-
"domain": "contoso"
54
-
},
55
-
"maintainer": {
56
-
"domain": "fabrikam"
57
-
},
58
-
"architect": {
59
-
"domain": "adventureWorks"
74
+
...
75
+
"userTags":
76
+
{
77
+
"anniversary": "2002-05-19",
78
+
"favoriteMovie": "Princess Bride"
60
79
}
61
80
}
62
81
```
63
82
64
-
### HTTP calls examples
83
+
### Setting a dictionary value
84
+
The following example shows setting a dictionary value. If "hairColor" already exists, it is updated, otherwise it is added.
65
85
66
-
In this set of examples, we model a **roles** property of dictionary type on the user entity, which is exposed by the users entity set.
86
+
```http
87
+
PATCH /item/userTags
88
+
```
89
+
```json
90
+
{
91
+
"hairColor": "purple"
92
+
}
93
+
```
67
94
68
-
#### Get an entry from the dictionary
95
+
### Deleting a dictionary value
96
+
A dictionary value can be removed by setting the value to null.
97
+
```http
98
+
PATCH /item/userTags
99
+
```
100
+
```json
101
+
{
102
+
"hairColor": null
103
+
}
104
+
```
105
+
106
+
### Declaring a complex typed dictionary
107
+
Dictionaries can also contain complex types whose values may be constrained to a particular set of complex types.
108
+
109
+
The following example defines a complex type **roleSettings**, an **assignedRoleGroupDictionary** that contains **roleSettings**, and an **assignedRoles** property that uses the dictionary..
### Reading a entity with a complex-typed dictionary
134
+
135
+
The following example illustrates reading an entity containing the complex-typed dictionary "assignedRoles".
69
136
70
137
```HTTP
71
-
GET https://graph.microsoft.com/v1.0/users/10/roles/author
138
+
GET /users/10
72
139
```
73
140
74
141
Response:
75
142
76
143
```json
77
144
{
78
-
"domain": "contoso"
145
+
"id": "10",
146
+
"displayName": "Jane Smith",
147
+
"assignedRoles": {
148
+
"author": {
149
+
"domain": "contoso"
150
+
},
151
+
"maintainer": {
152
+
"domain": "fabrikam"
153
+
},
154
+
"architect": {
155
+
"domain": "adventureWorks"
156
+
}
157
+
}
79
158
}
80
159
```
81
160
82
-
#### Get the dictionary
161
+
### Reading the dictionary property
162
+
The following example shows getting just the "assignedRoles" dictionary property.
83
163
84
164
```HTTP
85
-
GET https://graph.microsoft.com/v1.0/users/10/roles
165
+
GET /users/10/assignedRoles
86
166
```
87
167
88
168
Response:
@@ -101,47 +181,54 @@ Response:
101
181
}
102
182
```
103
183
104
-
#### Get the entity with the dictionary
184
+
#### Reading an individual entry from the dictionary
185
+
The following example shows reading a single complex-typed entry named "author" from the "assignedRoles" dictionary.
105
186
106
187
```HTTP
107
-
GET https://graph.microsoft.com/v1.0/users/10
188
+
GET /users/10/assingedRoles/author
108
189
```
109
190
110
191
Response:
111
192
112
193
```json
113
194
{
114
-
"id": "10",
115
-
"displayName": "Jane Smith",
116
-
"roles": {
117
-
"author": {
118
-
"domain": "contoso"
119
-
},
120
-
"maintainer": {
121
-
"domain": "fabrikam"
122
-
},
123
-
"architect": {
124
-
"domain": "adventureWorks"
125
-
}
126
-
}
195
+
"domain": "contoso"
127
196
}
128
197
```
129
198
130
-
#### Create an entry in the dictionary
199
+
#### Setting an individual entry in the dictionary
200
+
The following examples shows updating the dictionary to set the value for the "author" entry. If the "author" entry does not exists it is added with the specified values; otherwise, if the "author" entry already exists, it is updated with the specified values (unspecified values are left unchanged).
131
201
132
202
```HTTP
133
-
POST https://graph.microsoft.com/v1.0/users/10/roles/author
134
-
203
+
PATCH /users/10/assignedRoles/author
204
+
```
205
+
```json
135
206
{
136
-
"domain": "contoso"
207
+
"author" : {
208
+
"domain": "contoso"
209
+
}
137
210
}
138
211
```
139
212
140
-
#### Update the dictionary
213
+
#### Deleting an individual entry from the dictionary
214
+
The following example shows deleting the "author" entry by setting its value to null.
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**.
184
-
185
-
```xml
186
-
<ComplexTypeName="roleSettings">
187
-
<Property Name ="domain"Type="Edm.String"Nullable="false" />
0 commit comments