In this tutorial, you lean how to use open extensions.
Imagine you're building an application that's available on multiple client platforms, such as desktop and mobile. You want to the app's users to configure their UI experience so it's consistent no matter which device they use to sign in.
For this scenario, this article shows you how to:
- Represent some roaming profile information about the user using open extensions.
- Query the user and return the roaming profile.
- Change the user's roaming profile information stored in the open extension.
- Delete the user's roaming profile information.
Note
Apart from users, open extensions are also supported and can be managed for other resource types.
Prerequisites
To reproduce the steps in this article, you need the following privileges:
- Sign in to an API client such as Graph Explorer as the user you want to store the roaming profile for.
- Grant the app the User.ReadWrite delegated permission for the signed-in user.
The user signs in to the app and configures the look and feel of the app. These app settings should roam so that the user gets the same experience on whatever device they sign in to the app from. The app calls Microsoft Graph by running the following request to add the roaming profile information to the signed-in user's resource object.
Request
POST https://graph.microsoft.com/v1.0/me/extensions
Content-type: application/json
{
"@odata.type":"microsoft.graph.openTypeExtension",
"extensionName":"com.contoso.roamingSettings",
"theme":"dark",
"color":"purple",
"lang":"Japanese"
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new OpenTypeExtension
{
OdataType = "microsoft.graph.openTypeExtension",
ExtensionName = "com.contoso.roamingSettings",
AdditionalData = new Dictionary<string, object>
{
{
"theme" , "dark"
},
{
"color" , "purple"
},
{
"lang" , "Japanese"
},
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Me.Extensions.PostAsync(requestBody);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
mgc users extensions create --user-id {user-id} --body '{\
"@odata.type":"microsoft.graph.openTypeExtension",\
"extensionName":"com.contoso.roamingSettings",\
"theme":"dark",\
"color":"purple",\
"lang":"Japanese"\
}\
'
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
//other-imports
)
requestBody := graphmodels.NewExtension()
extensionName := "com.contoso.roamingSettings"
requestBody.SetExtensionName(&extensionName)
additionalData := map[string]interface{}{
"theme" : "dark",
"color" : "purple",
"lang" : "Japanese",
}
requestBody.SetAdditionalData(additionalData)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
extensions, err := graphClient.Me().Extensions().Post(context.Background(), requestBody, nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
OpenTypeExtension extension = new OpenTypeExtension();
extension.setOdataType("microsoft.graph.openTypeExtension");
extension.setExtensionName("com.contoso.roamingSettings");
HashMap<String, Object> additionalData = new HashMap<String, Object>();
additionalData.put("theme", "dark");
additionalData.put("color", "purple");
additionalData.put("lang", "Japanese");
extension.setAdditionalData(additionalData);
Extension result = graphClient.me().extensions().post(extension);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
const extension = {
'@odata.type':'microsoft.graph.openTypeExtension',
extensionName: 'com.contoso.roamingSettings',
theme: 'dark',
color: 'purple',
lang: 'Japanese'
};
await client.api('/me/extensions')
.post(extension);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Graph\Generated\Models\OpenTypeExtension;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new OpenTypeExtension();
$requestBody->setOdataType('microsoft.graph.openTypeExtension');
$requestBody->setExtensionName('com.contoso.roamingSettings');
$additionalData = [
'theme' => 'dark',
'color' => 'purple',
'lang' => 'Japanese',
];
$requestBody->setAdditionalData($additionalData);
$result = $graphServiceClient->me()->extensions()->post($requestBody)->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Import-Module Microsoft.Graph.Users
$params = @{
"@odata.type" = "microsoft.graph.openTypeExtension"
extensionName = "com.contoso.roamingSettings"
theme = "dark"
color = "purple"
lang = "Japanese"
}
# A UPN can also be used as -UserId.
New-MgUserExtension -UserId $userId -BodyParameter $params
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.open_type_extension import OpenTypeExtension
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = OpenTypeExtension(
odata_type = "microsoft.graph.openTypeExtension",
extension_name = "com.contoso.roamingSettings",
additional_data = {
"theme" : "dark",
"color" : "purple",
"lang" : "Japanese",
}
)
result = await graph_client.me.extensions.post(request_body)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
HTTP/1.1 201 Created
Content-Type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('376bdbfc-e41f-4082-a8cf-b31731465eeb')/extensions/$entity",
"@odata.type": "#microsoft.graph.openTypeExtension",
"extensionName": "com.contoso.roamingSettings",
"theme": "dark",
"color": "purple",
"lang": "Japanese",
"id": "com.contoso.roamingSettings"
}
When the user signs in to the app from another device, the app calls Microsoft Graph to retrieve their profile details including the extensions navigation property that contains their roaming settings, then uses this data to provide the same experience as on the other device.
Request
GET https://graph.microsoft.com/v1.0/me?$select=id,displayName,mail,mobilePhone&$expand=extensions
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Me.GetAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Select = new string []{ "id","displayName","mail","mobilePhone" };
requestConfiguration.QueryParameters.Expand = new string []{ "extensions" };
});
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphusers "github.com/microsoftgraph/msgraph-sdk-go/users"
//other-imports
)
requestParameters := &graphusers.MeRequestBuilderGetQueryParameters{
Select: [] string {"id","displayName","mail","mobilePhone"},
Expand: [] string {"extensions"},
}
configuration := &graphusers.MeRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters,
}
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
me, err := graphClient.Me().Get(context.Background(), configuration)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
User result = graphClient.me().get(requestConfiguration -> {
requestConfiguration.queryParameters.select = new String []{"id", "displayName", "mail", "mobilePhone"};
requestConfiguration.queryParameters.expand = new String []{"extensions"};
});
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
let user = await client.api('/me')
.expand('extensions')
.select('id,displayName,mail,mobilePhone')
.get();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Graph\Generated\Me\MeRequestBuilderGetRequestConfiguration;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestConfiguration = new UserItemRequestBuilderGetRequestConfiguration();
$queryParameters = UserItemRequestBuilderGetRequestConfiguration::createQueryParameters();
$queryParameters->select = ["id","displayName","mail","mobilePhone"];
$queryParameters->expand = ["extensions"];
$requestConfiguration->queryParameters = $queryParameters;
$result = $graphServiceClient->me()->get($requestConfiguration)->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Import-Module Microsoft.Graph.Users
# A UPN can also be used as -UserId.
Get-MgUser -UserId $userId -Property "id,displayName,mail,mobilePhone" -ExpandProperty "extensions"
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.me.me_request_builder import MeRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
query_params = MeRequestBuilder.MeRequestBuilderGetQueryParameters(
select = ["id","displayName","mail","mobilePhone"],
expand = ["extensions"],
)
request_configuration = RequestConfiguration(
query_parameters = query_params,
)
result = await graph_client.me.get(request_configuration = request_configuration)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users(id,displayName,mail,mobilePhone,extensions())/$entity",
"@microsoft.graph.tips": "Use $select to choose only the properties your app needs, as this can lead to performance improvements. For example: GET me?$select=signInActivity,accountEnabled",
"id": "376bdbfc-e41f-4082-a8cf-b31731465eeb",
"displayName": "Raul Razo",
"mail": null,
"mobilePhone": null,
"[email protected]": "https://graph.microsoft.com/v1.0/$metadata#users('376bdbfc-e41f-4082-a8cf-b31731465eeb')/extensions",
"extensions": [
{
"@odata.type": "#microsoft.graph.openTypeExtension",
"extensionName": "com.contoso.roamingSettings",
"theme": "dark",
"color": "purple",
"lang": "Japanese",
"id": "com.contoso.roamingSettings"
}
]
}
The user can choose to change their roaming profile information. The app calls Microsoft Graph by running the following query. The request returns a 204 No Content
response code.
You must include all properties in the request body, even if you want to update only a subset. Otherwise, Microsoft Graph removes the unspecified properties. To delete data but keep a property, set the property value to null
.
PATCH https://graph.microsoft.com/v1.0/me/extensions/com.contoso.roamingSettings
Content-type: application/json
{
"theme":"light",
"color":"purple",
"lang":"Swahili"
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Models;
var requestBody = new Extension
{
AdditionalData = new Dictionary<string, object>
{
{
"theme" , "light"
},
{
"color" , "purple"
},
{
"lang" , "Swahili"
},
},
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Me.Extensions["{extension-id}"].PatchAsync(requestBody);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
mgc users extensions patch --user-id {user-id} --extension-id {extension-id} --body '{\
"theme":"light",\
"color":"purple",\
"lang":"Swahili"\
}\
'
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphmodels "github.com/microsoftgraph/msgraph-sdk-go/models"
//other-imports
)
requestBody := graphmodels.NewExtension()
additionalData := map[string]interface{}{
"theme" : "light",
"color" : "purple",
"lang" : "Swahili",
}
requestBody.SetAdditionalData(additionalData)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
extensions, err := graphClient.Me().Extensions().ByExtensionId("extension-id").Patch(context.Background(), requestBody, nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
Extension extension = new Extension();
HashMap<String, Object> additionalData = new HashMap<String, Object>();
additionalData.put("theme", "light");
additionalData.put("color", "purple");
additionalData.put("lang", "Swahili");
extension.setAdditionalData(additionalData);
Extension result = graphClient.me().extensions().byExtensionId("{extension-id}").patch(extension);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
const extension = {
theme: 'light',
color: 'purple',
lang: 'Swahili'
};
await client.api('/me/extensions/com.contoso.roamingSettings')
.update(extension);
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Graph\Generated\Models\Extension;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new Extension();
$additionalData = [
'theme' => 'light',
'color' => 'purple',
'lang' => 'Swahili',
];
$requestBody->setAdditionalData($additionalData);
$result = $graphServiceClient->me()->extensions()->byExtensionId('extension-id')->patch($requestBody)->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Import-Module Microsoft.Graph.Users
$params = @{
theme = "light"
color = "purple"
lang = "Swahili"
}
# A UPN can also be used as -UserId.
Update-MgUserExtension -UserId $userId -ExtensionId $extensionId -BodyParameter $params
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.models.extension import Extension
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = Extension(
additional_data = {
"theme" : "light",
"color" : "purple",
"lang" : "Swahili",
}
)
result = await graph_client.me.extensions.by_extension_id('extension-id').patch(request_body)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Step 4. Delete a user's roaming profile
The user decides that they don't want a roaming profile anymore. To delete the extension property, the app calls Microsoft Graph by running the following request. The request returns a 204 No Content
response code.
DELETE https://graph.microsoft.com/v1.0/me/extensions/com.contoso.roamingSettings
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
await graphClient.Me.Extensions["{extension-id}"].DeleteAsync();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
//other-imports
)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
graphClient.Me().Extensions().ByExtensionId("extension-id").Delete(context.Background(), nil)
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
graphClient.me().extensions().byExtensionId("{extension-id}").delete();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
const options = {
authProvider,
};
const client = Client.init(options);
await client.api('/me/extensions/com.contoso.roamingSettings')
.delete();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
<?php
use Microsoft\Graph\GraphServiceClient;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$graphServiceClient->me()->extensions()->byExtensionId('extension-id')->delete()->wait();
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Import-Module Microsoft.Graph.Users
# A UPN can also be used as -UserId.
Remove-MgUserExtension -UserId $userId -ExtensionId $extensionId
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
await graph_client.me.extensions.by_extension_id('extension-id').delete()
Read the SDK documentation for details on how to add the SDK to your project and create an authProvider instance.
Related content