Skip to content

Commit 9ebf9b9

Browse files
address PR comments
1 parent d3b55d1 commit 9ebf9b9

File tree

1 file changed

+52
-45
lines changed

1 file changed

+52
-45
lines changed

articles/communication-services/concepts/raw-id-use-cases.md

Lines changed: 52 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ CommunicationIdentifier has the following advantages:
2424
- Allows using a switch case by type to address different application flows.
2525
- Allows restricting communication to specific types.
2626

27-
On top of these advantages, the ability to instantiate a *CommunicationIdentifier* from Raw ID and being able to retrieve an underlying Raw ID of a *CommunicationIdentifier* of a certain type (for example, `MicrosoftTeamsUserIdentifier`, `PhoneNumberIdentifier`, etc.) makes the following scenarios easier to implement:
27+
On top of this, the *CommunicationIdentifier* and the derived types (`MicrosoftTeamsUserIdentifier`, `PhoneNumberIdentifier`, etc.) can be converted to its string representation (Raw ID), making the following scenarios easier to implement:
2828
- Extract identifier details from Raw IDs and use them to call other APIs (such as the Microsoft Graph API) to provide a rich experience for communication participants.
2929
- Store identifiers in a database and use them as keys.
3030
- Use identifiers as keys in dictionaries.
@@ -51,7 +51,7 @@ CommunicationIdentifier communicationIdentifier = CommunicationIdentifier.FromRa
5151
You can find more platform-specific examples in the following article: [Understand identifier types](./identifiers.md)
5252

5353
## Storing CommunicationIdentifier in a database
54-
Depending on your scenario, you may want to store CommunicationIdentifier in a database. Each type of CommunicationIdentifier has an underlying Raw ID, which is stable, globally unique, and deterministic. The guaranteed uniqueness allows choosing it as a key in the storage. You can map ACS users' IDs to the users coming from the Contoso identity provider.
54+
One of the typical jobs that may be required from you is mapping ACS users to users coming from Contoso user database or identity provider. This is usually achieved by adding an extra column or field in Contoso user DB or Identity Provider. However, given the characteristics of the Raw ID (stable, globally unique, and deterministic), you may as well choose it as a primary key for the user storage.
5555

5656
Assuming a `ContosoUser` is a class that represents a user of your application, and you want to save it along with a corresponding CommunicationIdentifier to the database. The original value for a `CommunicationIdentifier` can come from the Communication Identity, Calling or Chat APIs or from a custom Contoso API but can be represented as a `string` data type in your programming language no matter what the underlying type is:
5757

@@ -93,53 +93,61 @@ public void GetFromDatabase()
9393
It will return `CommunicationUserIdentifier`, `PhoneNumberIdentifier`, `MicrosoftTeamsUserIdentifier` or `UnknownIdentifier` based on the identifier type.
9494

9595
## Storing CommunicationIdentifier in collections
96-
If your scenario requires working with several *CommunicationIdentifier* objects in memory, you may want to store them in a collection (dictionary, list, hash set, etc.). A collection is useful, for example, for maintaining a list of call or chat participants. As the hashing logic relies on the value of a Raw ID, you can use *CommunicationIdentifier* in collections that require elements to have a reliable hashing behavior. The following examples demonstrate adding *CommunicationIdentifier* objects to different types of collections and checking if they're contained in a collection by instantiating new identifiers from a Raw ID value. The same approach also works for identifiers that are converted to an *UnknownIdentifier* type. This type is reserved for any new types of identifiers that might be introduced in the future, to maintain the compatibility in older SDK versions.
96+
If your scenario requires working with several *CommunicationIdentifier* objects in memory, you may want to store them in a collection (dictionary, list, hash set, etc.). A collection is useful, for example, for maintaining a list of call or chat participants. As the hashing logic relies on the value of a Raw ID, you can use *CommunicationIdentifier* in collections that require elements to have a reliable hashing behavior. The following examples demonstrate adding *CommunicationIdentifier* objects to different types of collections and checking if they're contained in a collection by instantiating new identifiers from a Raw ID value.
97+
98+
The following example shows how Raw ID can be used as a key in a dictionary to store user's messages:
9799

98100
```csharp
99101
public void StoreMessagesForContosoUsers()
102+
{
103+
var communicationUser = new CommunicationUserIdentifier("8:acs:bbbcbc1e-9f06-482a-b5d8-20e3f26ef0cd_45ab2481-1c1c-4005-be24-0ffb879b1130");
104+
var teamsUserUser = new CommunicationUserIdentifier("45ab2481-1c1c-4005-be24-0ffb879b1130");
105+
106+
// A dictionary with a CommunicationIdentifier as key might be used to store messages of a user.
107+
var userMessages = new Dictionary<string, List<Message>>
100108
{
101-
// A dictionary with a CommunicationIdentifier as key might be used to store messages of a user.
102-
var userMessages = new Dictionary<CommunicationIdentifier, List<Message>>
103-
{
104-
{ new CommunicationUserIdentifier("8:acs:bbbcbc1e-9f06-482a-b5d8-20e3f26ef0cd_45ab2481-1c1c-4005-be24-0ffb879b1130"), new List<Message>() },
105-
{ new MicrosoftTeamsUserIdentifier("45ab2481-1c1c-4005-be24-0ffb879b1130"), new List<Message>() },
106-
};
107-
108-
// Retrieve messages for a user based on their Raw ID.
109-
var messages = userMessages[CommunicationIdentifier.FromRawId("8:acs:bbbcbc1e-9f06-482a-b5d8-20e3f26ef0cd_45ab2481-1c1c-4005-be24-0ffb879b1130")];
110-
}
109+
{ communicationUser.RawId, new List<Message>() },
110+
{ teamsUserUser.RawId, new List<Message>() },
111+
};
112+
113+
// Retrieve messages for a user based on their Raw ID.
114+
var messages = userMessages[communicationUser.RawId];
115+
}
111116
```
112117

118+
As the hashing logic relies on the value of a Raw ID, you can use `CommunicationIdentifier` itself as a key in a dictionary directly:
119+
113120
```csharp
114-
public void StoreUniqueContosoUsers()
121+
public void StoreMessagesForContosoUsers()
122+
{
123+
// A dictionary with a CommunicationIdentifier as key might be used to store messages of a user.
124+
var userMessages = new Dictionary<CommunicationIdentifier, List<Message>>
115125
{
116-
// A hash set of unique users of a Contoso application.
117-
var users = new HashSet<CommunicationIdentifier>
118-
{
119-
new PhoneNumberIdentifier("+14255550123"),
120-
new UnknownIdentifier("28:45ab2481-1c1c-4005-be24-0ffb879b1130")
121-
};
122-
123-
// Implement custom flow for a new communication user.
124-
if (users.Contains(CommunicationIdentifier.FromRawId("4:+14255550123"))){
125-
//...
126-
}
127-
}
126+
{ new CommunicationUserIdentifier("8:acs:bbbcbc1e-9f06-482a-b5d8-20e3f26ef0cd_45ab2481-1c1c-4005-be24-0ffb879b1130"), new List<Message>() },
127+
{ new MicrosoftTeamsUserIdentifier("45ab2481-1c1c-4005-be24-0ffb879b1130"), new List<Message>() },
128+
};
129+
130+
// Retrieve messages for a user based on their Raw ID.
131+
var messages = userMessages[CommunicationIdentifier.FromRawId("8:acs:bbbcbc1e-9f06-482a-b5d8-20e3f26ef0cd_45ab2481-1c1c-4005-be24-0ffb879b1130")];
132+
}
128133
```
129134

135+
Hashing logic that relies on the value of a Raw ID, also allows you to add `CommunicationIdentifier` objects to hash sets:
130136
```csharp
131-
public void StoreContosoUsersInOrderTheyJoin()
137+
public void StoreUniqueContosoUsers()
138+
{
139+
// A hash set of unique users of a Contoso application.
140+
var users = new HashSet<CommunicationIdentifier>
132141
{
133-
// A list set of users that can be used in aggregate functions or statistics calculation.
134-
var participants = new List<CommunicationIdentifier>
135-
{
136-
new MicrosoftTeamsUserIdentifier("45ab2481-1c1c-4005-be24-0ffb879b1130"),
137-
new UnknownIdentifier("28:45ab2481-1c1c-4005-be24-0ffb879b1130")
138-
};
139-
140-
// Add a new participant when having a Raw ID.
141-
participants.Add(CommunicationIdentifier.FromRawId("8:orgid:45ab2481-1c1c-4005-be24-0ffb879b1130"));
142-
}
142+
new PhoneNumberIdentifier("+14255550123"),
143+
new UnknownIdentifier("28:45ab2481-1c1c-4005-be24-0ffb879b1130")
144+
};
145+
146+
// Implement custom flow for a new communication user.
147+
if (users.Contains(CommunicationIdentifier.FromRawId("4:+14255550123"))){
148+
//...
149+
}
150+
}
143151
```
144152

145153
Another use case is using Raw IDs in mobile applications to identify participants. You can inject the participant view data for remote participant if you want to handle this information locally in the UI library without sending it to Azure Communication Services.
@@ -165,26 +173,26 @@ callComposite.events.onRemoteParticipantJoined = { identifiers in
165173
```
166174

167175
## Using Raw ID as key in REST API paths
168-
When designing a REST API, you can have endpoints that have a unique identifier for your application user in a form of a Raw ID string. If the identifier consists of several parts (like ObjectID, cloud name, etc. if you're using `MicrosoftTeamsUserIdentifier`), using Raw ID allows you to address the entity in the URL path instead of passing the whole composite object as a JSON in the body. So that you can have a more intuitive REST CRUD API.
176+
When designing a REST API, you can have endpoints that either accept a `CommunicationIdentifier` or a Raw ID string. If the identifier consists of several parts (like ObjectID, cloud name, etc. if you're using `MicrosoftTeamsUserIdentifier`), you might need to pass it in the request body. However, using Raw ID allows you to address the entity in the URL path instead of passing the whole composite object as a JSON in the body. So that you can have a more intuitive REST CRUD API.
169177

170178
```csharp
171179
public async Task UseIdentifierInPath()
172180
{
173-
ContosoUser user = GetFromDb("[email protected]");
181+
CommunicationIdentifier user = GetFromDb("[email protected]");
174182

175-
using HttpResponseMessage response = await client.GetAsync($"https://contoso.com/v1.0/users/{user.CommunicationId}/profile");
183+
using HttpResponseMessage response = await client.GetAsync($"https://contoso.com/v1.0/users/{user.RawId}/profile");
176184
response.EnsureSuccessStatusCode();
177185
}
178186
```
179187

180188
## Extracting identifier details from Raw IDs.
181189
Consistent underlying Raw ID allows:
182190
- Deserializing to the right identifier type (based on which you can adjust the flow of your app).
183-
- Extracting details of identifiers (such as an oid for `msteamsuser`).
191+
- Extracting details of identifiers (such as an oid for `MicrosoftTeamsUserIdentifier`).
184192

185193
The example shows both benefits:
186194
- The type allows you to decide where to take the avatar from.
187-
- The decomposed details allow you to query the api in the right way.
195+
- The decomposed details allow you to query the API in the right way.
188196

189197
```csharp
190198
public void ExtractIdentifierDetails()
@@ -210,9 +218,9 @@ public void ExtractIdentifierDetails()
210218
You can access properties or methods for a specific *CommunicationIdentifier* type that is stored in a Contoso database in a form of a string (Raw ID).
211219

212220
## Using Raw IDs as key in UI frameworks
213-
It's possible to use Raw ID of an identifier as a key in UI components to track a certain user and avoid unnecessary re-rendering and API calls.
221+
It's possible to use Raw ID of an identifier as a key in UI components to track a certain user and avoid unnecessary re-rendering and API calls. In the example, we're changing the order of how users are rendered in a list. In real world, we might want to show new users first or re-order users based on some condition (for example, hand raised). For the sake of simplicity, the following example just reverses the order in which the users are rendered.
214222

215-
```react
223+
```javascript
216224
import { getIdentifierRawId } from '@azure/communication-common';
217225

218226
function CommunicationParticipants() {
@@ -223,7 +231,6 @@ function CommunicationParticipants() {
223231
// Each list item should have a unique key. Raw ID can be used as such key.
224232
<ListUser item={user} key={user.id} />
225233
))}
226-
// We might want to show new users first or re-oder users based on some condition (for example, hand raised).
227234
<button onClick={() => setUsers(users.slice().reverse())}>Reverse</button>
228235
</div>
229236
);

0 commit comments

Comments
 (0)