Graph
Graph is the gateway to data and intelligence in Microsoft 265. In Microsoft 365, three main components facilitate data access and flow:
Graph
Single endpoint:https://graph.microsoft.com. REST or SDK. Includes user, device identity, access, compliance and security management services.Graph connectors
Used to deliver data into Graph from external sources.Graph Data Connect
Used to deliver Graph data into popular Azure data stores, which can then be used to build intelligent applications.
Querying with REST
Uses an OData namespace microsoft.graph. A few API sets are defined in sub-namespaces, such as call records API which are in microsoft.graph.callRecords.
It is generally safe to assume that types, methods and enumerations are part of the microsoft.graph namespace.
GET|POST|PATCH|PUT|DELETE
https://graph.microsoft.com/{version}/{resource}?{query-parameters}
{version}- Graph version{resource}- Graph resource you are referencingGETandDELETE- no request body requiredPOST,PATCHandPUT- JSON request body required
For numerated data, @odata.nextLink contains a URL for the next page.
Resources
A resource can be an entity or complex type. Unlike complex types, entities always include an id property.
REST Url always includes the resource you are interacting with, such as me, user, group, drive and site. Top level resources often also include relationships, which can be used to access more specific resources, like me/messages, me/drive etc.
You can also interact with methods in this way, for example me/sendMail to send an email.
Different resources may require different permissions to access. Writing to a resource typically requires more permissions than reading.
Query parameters
Standard OData system query options:
GET https://graph.microsoft.com/v1.0/me/messages?
filter=emailAddress eq 'jon@contoso.com'
- Think Service Search
Querying with SDKs
The Graph SDKs container two components:
Service library
Contains models and request builders generated from Graph metadata.Core library
Provides features that make working with Graph easier, like support for pagination, batch requests, retry handling, payload compression and more.
Three NuGet packages:
Microsoft.Graph- service libraryMicrosoft.Graph.Beta- service library withbetasupportMicrosoft.Graph.Core- core library
Creating a client
Clients are designed to be singleton.
var scopes = new[] { "User.Read" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Value from app registration
var clientId = "YOUR_CLIENT_ID";
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// Callback function that receives the user prompt
// Prompt contains the generated device code that you must
// enter during the auth process in the browser
Func<DeviceCodeInfo, CancellationToken, Task> callback = (code, cancellation) => {
Console.WriteLine(code.Message);
return Task.FromResult(0);
};
// /dotnet/api/azure.identity.devicecodecredential
var deviceCodeCredential = new DeviceCodeCredential(
callback, tenantId, clientId, options);
var graphClient = new GraphServiceClient(deviceCodeCredential, scopes);
Point read
// GET https://graph.microsoft.com/v1.0/me
var user = await graphClient.Me
.GetAsync();
Lists
// GET https://graph.microsoft.com/v1.0/me/messages?
// $select=subject,sender&$filter=subject eq 'Hello world'
var messages = await graphClient.Me.Messages
.GetAsync(requestConfig =>
{
requestConfig.QueryParameters.Select =
["subject", "sender"];
requestConfig.QueryParameters.Filter =
"subject eq 'Hello world'";
});
Delete
// DELETE https://graph.microsoft.com/v1.0/me/messages/{message-id}
// messageId is a string containing the id property of the message
await graphClient.Me.Messages[messageId]
.DeleteAsync();
Create
// POST https://graph.microsoft.com/v1.0/me/calendars
var calendar = new Calendar
{
Name = "Volunteer",
};
var newCalendar = await graphClient.Me.Calendars
.PostAsync(calendar);
Best practice
- Use the MSAL library to acquire an OAuth 2.0 access token
- Standard consent and authorisation best practice:
- Least privilege
- Delegated permissions if signed in user is present
- Configure permissions appropriately for user or admin consent
- Expect that other tenants may had authorisation policies that break your app and handle 403s appropriately
- Always handle possible pagination for numerated data scenarios
- Handle evolvable enums
- Graph sometimes adds enumerations but hides them in responses so as not to create breaking changes
- Optionally handle these manually via an added
preferheader
- Only cache if absolutely necessary