Skip to content

Commit e973edb

Browse files
authored
Merge pull request #347 from microsoft/feat/alternate-key
Add Alternate Key Pattern
2 parents ebe862f + be6a0c2 commit e973edb

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed

graph/patterns/alternate-key.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Alternate Key Pattern
2+
3+
Microsoft Graph API Design Pattern
4+
5+
_The Alternate Key Pattern provides the ability to query for a single, specific resource identifiable through an alternative set of properties that is not its primary key_
6+
7+
## Problem
8+
9+
---
10+
11+
The resources exposed in Graph are identified through a Primary Key - which guarantees uniqueness inside the same resource type. Often though, that same resource can also be uniquely identified by an alternative, more convenient property (or set of properties) that provides a better developer experience.
12+
13+
Take a look at the `user` resource: while the `id` remains a perfectly valid way to get the resource details, the `mail` address is also an unique property that could be used to identify it.
14+
15+
While it is still possible to use the `$filter` query parameter, such as
16+
17+
`GET https://graph.microsoft.com/v1.0/users?$filter=mail eq '[email protected]'`, the returned result is wrapped in an array that needs to be unpacked.
18+
19+
## Solution
20+
21+
---
22+
23+
Resource addressing via an alternative key can be achieved using the same parentheses-style convention as for the canonical key, with one difference: single-part alternate keys MUST specify the key property name to unambiguously determine the alternate key. (Note: this is a hypothetical sample)
24+
25+
https://graph.microsoft.com/v1.0/users(0) - Retrieves the employee with ID = 0
26+
https://graph.microsoft.com/v1.0/users(email='[email protected]') Retrieves the employee with the email matching `[email protected]`
27+
28+
## When to Use this Pattern
29+
30+
---
31+
32+
This pattern works and makes sense when the alternate key is good enough to identify a single resource and provides an useful alternative to the client.
33+
34+
## Example
35+
36+
---
37+
38+
The same user identified via the alternate key SSN, the canonical (primary) key ID using the non-canonical long form with specified key property name, and the canonical short form without key property name
39+
40+
Declare `mail` and `ssn` as alternate keys on an entity:
41+
42+
```xml
43+
<EntityType Name="user">
44+
<Key>
45+
<PropertyRef Name="id" />
46+
</Key>
47+
<Property Name="id" Type="Edm.Int32" />
48+
49+
<Property Name="mail" Type="Edm.String" />
50+
<Property Name="ssn" Type="Edm.String" />
51+
<Annotation Term="Keys.AlternateKeys">
52+
<Collection>
53+
<Record>
54+
<PropertyValue Property="Key">
55+
<Collection>
56+
<Record>
57+
<PropertyValue Property="Name" PropertyPath="mail" />
58+
</Record>
59+
</Collection>
60+
</PropertyValue>
61+
</Record>
62+
<Record>
63+
<PropertyValue Property="Key">
64+
<Collection>
65+
<Record>
66+
<PropertyValue Property="Name" PropertyPath="ssn" />
67+
</Record>
68+
</Collection>
69+
</PropertyValue>
70+
</Record>
71+
</Collection>
72+
</Annotation>
73+
</EntityType>
74+
```
75+
76+
1. Get a specific resource through `$filter`:
77+
78+
```http
79+
GET https://graph.microsoft.com/v1.0/users/?$filter=ssn eq '123-45-6789'
80+
```
81+
82+
```json
83+
{
84+
"value": [
85+
{
86+
"givenName": "Bob",
87+
"jobTitle": "Retail Manager",
88+
"mail": "[email protected]",
89+
"mobilePhone": "+1 425 555 0109",
90+
"officeLocation": "18/2111",
91+
"preferredLanguage": "en-US",
92+
"surname": "Vance",
93+
"userPrincipalName": "[email protected]",
94+
"id": "1a89ade6-9f59-4fea-a139-23f84e3aef66"
95+
}
96+
]
97+
}
98+
```
99+
100+
2. Get a specific resource either through its primary key, or through the two alternate keys:
101+
102+
```http
103+
GET https://graph.microsoft.com/v1.0/users/1a89ade6-9f59-4fea-a139-23f84e3aef66
104+
GET https://graph.microsoft.com/v1.0/users(ssn='123-45-6789')
105+
GET https://graph.microsoft.com/v1.0/users(mail='[email protected]')
106+
```
107+
108+
**NOTE:** When requesting a resource through its primary key you might want to prefer to use key-as-segment (as shown above). Also, the key-as-segment does not work for alternate keys.
109+
110+
All of the 3 will yield the sare response:
111+
112+
```json
113+
{
114+
"givenName": "Bob",
115+
"jobTitle": "Retail Manager",
116+
"mail": "[email protected]",
117+
"mobilePhone": "+1 425 555 0109",
118+
"officeLocation": "18/2111",
119+
"preferredLanguage": "en-US",
120+
"ssn": "123-45-6789",
121+
"surname": "Vance",
122+
"userPrincipalName": "[email protected]",
123+
"id": "1a89ade6-9f59-4fea-a139-23f84e3aef66"
124+
}
125+
```
126+
127+
3. Requesting a resource for an unsupported alternate key property
128+
129+
```http
130+
GET https://graph.microsoft.com/v1.0/users(name='Bob')
131+
132+
400 Bad Request
133+
```

0 commit comments

Comments
 (0)