Microsoft Graph API – Difference between Teams and Groups end points

I have been trying to map my brain thinking to talk what I have learnt around Microsoft Teams and Group API. Recently microsoft graph team has updated a lot of end points. If you look at the change log URL – https://developer.microsoft.com/en-us/graph/docs/concepts/changelog#july-2018, you will find that a lot of beta end points which were created on groups like channels, are now available around teams.

So what’s the problem?

There is no problem. I say this is great to fix end points and make them according to what make sense.

You, as developer or end user, might know by now that Groups and Teams share common group. Let’s see how Microsoft Graph API handle this.

Difference –

Microsoft Teams is a chat based workspace. Based on how it is designed, there are channels to separate conversations. The conversations are Chat Threads which has root message and replied messages. Each of the message is Chat Message.

While on the other hand, Groups are designed to work with Exchange. Said that, Groups messages are Conversation thread and include posts also. Groups does not have container to separate conversations like channels.

Similarities –

Groups and Teams are two sides of one coin. They both share Notes, Plans, Drive (SharePoint site), Calendar and photo together.

When there is so much similarity then why am I writing this blog?

The common services works with both products, but in Graph API following are the key observations –

  1. Teams and Group share same ID.
  2. Microsoft Teams end point has
    1. Channel –> Chat thread –> Chat message
    2. Apps
    3. Operations [new end point without any documentation]
  3. Groups has end points for below services and more [more part cover Groups specific end points]
    1. Notes
    2. Drive
    3. Plans
    4. Calendar
    5. Photo

The following image shows how the API endpoints are designed and how the messages have similarities in two systems.

Teams With Graph

Advertisements

Microsoft Graph API – User End Point v1.0 vs Beta

I was working recently on user endpoint in Microsoft Graph API. As a general rule, I was working with v1.0 or General Available end point. Then I switched to see what’s new in beta end point. To my surprise, it has tons of information difference between both end points. The following table show the properties available in each end point –

V1.0 – https://graph.microsoft.com/v1.0/users Beta – https://graph.microsoft.com/beta/users
{
“id”: “87d349ed-44d7-43e1-9a83-5f2406dee5bd”,
“businessPhones”: [
“+1 425 555 0109”
],
“displayName”: “Adele Vance”,
“givenName”: “Adele”,
“jobTitle”: “Product Marketing Manager”,
“mail”: “AdeleV@M365x214355.onmicrosoft.com”,
“mobilePhone”: null,
“officeLocation”: “18/2111”,
“preferredLanguage”: “en-US”,
“surname”: “Vance”,
“userPrincipalName”: “AdeleV@M365x214355.onmicrosoft.com”
}
{
“id”: “87d349ed-44d7-43e1-9a83-5f2406dee5bd”,
“deletedDateTime”: null,
“accountEnabled”: true,
“ageGroup”: null,
“businessPhones”: [
“+1 425 555 0109”
],
“city”: “Bellevue”,
“createdDateTime”: “2017-07-29T03:03:26Z”,
“companyName”: null,
“consentProvidedForMinor”: null,
“country”: “United States”,
“department”: “Sales & Marketing”,
“displayName”: “Adele Vance”,
“employeeId”: null,
“givenName”: “Adele”,
“jobTitle”: “Product Marketing Manager”,
“legalAgeGroupClassification”: null,
“mail”: “AdeleV@M365x214355.onmicrosoft.com”,
“mailNickname”: “AdeleV”,
“mobilePhone”: null,
“onPremisesDomainName”: null,
“onPremisesImmutableId”: null,
“onPremisesLastSyncDateTime”: null,
“onPremisesSecurityIdentifier”: null,
“onPremisesSamAccountName”: null,
“onPremisesSyncEnabled”: null,
“onPremisesUserPrincipalName”: null,
“passwordPolicies”: “DisablePasswordExpiration”,
“passwordProfile”: null,
“officeLocation”: “18/2111”,
“postalCode”: “98004”,
“preferredDataLocation”: null,
“preferredLanguage”: “en-US”,
“proxyAddresses”: [
“SMTP:AdeleV@M365x214355.onmicrosoft.com”
],
“refreshTokensValidFromDateTime”: “2017-09-12T21:08:09Z”,
“showInAddressList”: null,
“imAddresses”: [
“AdeleV@M365x214355.onmicrosoft.com”
],
“isResourceAccount”: null,
“state”: “WA”,
“streetAddress”: “205 108th Ave. NE, Suite 400”,
“surname”: “Vance”,
“usageLocation”: “US”,
“userPrincipalName”: “AdeleV@M365x214355.onmicrosoft.com”,
“userType”: “Member”,
“extension_fe2174665583431c953114ff7268b7b3_Education_ObjectType”: “teacher”,
“extension_fe2174665583431c953114ff7268b7b3_Education_TeacherNumber”: “106”,
“assignedLicenses”: [
{
“disabledPlans”: [],
“skuId”: “c7df2760-2c81-4ef7-b578-5b5392b571df”
}
],
“assignedPlans”: [
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “Adallom”,
“servicePlanId”: “8c098270-9dd4-4350-9b30-ba4703f3b36b”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “SharePoint”,
“servicePlanId”: “e95bec33-7c88-4a70-8e19-b10bd9d0c014”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “SharePoint”,
“servicePlanId”: “5dbe027f-2339-4123-9542-606e4d348a72”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “exchange”,
“servicePlanId”: “efb87545-963c-4e0d-99df-69c6916d9eb0”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “MicrosoftCommunicationsOnline”,
“servicePlanId”: “0feaeb32-d00e-4d66-bd5a-43b5b83db82c”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “MicrosoftOffice”,
“servicePlanId”: “43de0ff5-c92c-492b-9116-175376d08c38”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “YammerEnterprise”,
“servicePlanId”: “7547a3fe-08ee-4ccb-b430-5077c5041653”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “RMSOnline”,
“servicePlanId”: “bea4c11e-220a-4e6d-8eb8-8ea15d019f90”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “ProjectWorkManagement”,
“servicePlanId”: “b737dad2-2f6c-4c65-90e3-ca563267e8b9”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “PowerBI”,
“servicePlanId”: “70d33638-9c74-4d01-bfd3-562de28bd4ba”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “MicrosoftCommunicationsOnline”,
“servicePlanId”: “3e26ee1f-8a5f-4d52-aee2-b81ce45c8f40”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “MicrosoftCommunicationsOnline”,
“servicePlanId”: “4828c8ec-dc2e-4779-b502-87ac9ce28ab7”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “Sway”,
“servicePlanId”: “a23b959c-7ce8-4e57-9140-b90eb88a9e97”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “exchange”,
“servicePlanId”: “34c0d7a0-a70f-4668-9238-47f9fc208882”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “exchange”,
“servicePlanId”: “9f431833-0334-42de-a7dc-70aa40db46db”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “exchange”,
“servicePlanId”: “4de31727-a228-4ec3-a5bf-8e45b5ca48cc”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “TeamspaceAPI”,
“servicePlanId”: “57ff2da0-773e-42df-b2af-ffb7a2317929”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “PowerAppsService”,
“servicePlanId”: “9c0dab89-a30c-4117-86e7-97bda240acd2”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “ProcessSimple”,
“servicePlanId”: “07699545-9485-468e-95b6-2fca3738be01”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “Deskless”,
“servicePlanId”: “8c7d2df8-86f0-4902-b2ed-a0458298f3b3”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “exchange”,
“servicePlanId”: “8e0c0a52-6a6c-4d40-8370-dd62790dcd70”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “MicrosoftStream”,
“servicePlanId”: “6c6042f5-6f01-4d67-b8c1-eb99d36eed3e”
},
{
“assignedDateTime”: “2017-07-29T03:03:25Z”,
“capabilityStatus”: “Enabled”,
“service”: “OfficeForms”,
“servicePlanId”: “e212cbc7-0961-4c40-9825-01117710dcb1”
}
],
“deviceKeys”: [],
“onPremisesExtensionAttributes”: {
“extensionAttribute1”: null,
“extensionAttribute2”: null,
“extensionAttribute3”: null,
“extensionAttribute4”: null,
“extensionAttribute5”: null,
“extensionAttribute6”: null,
“extensionAttribute7”: null,
“extensionAttribute8”: null,
“extensionAttribute9”: null,
“extensionAttribute10”: null,
“extensionAttribute11”: null,
“extensionAttribute12”: null,
“extensionAttribute13”: null,
“extensionAttribute14”: null,
“extensionAttribute15”: null
},
“onPremisesProvisioningErrors”: [],
“provisionedPlans”: [
{
“capabilityStatus”: “Enabled”,
“provisioningStatus”: “Success”,
“service”: “MicrosoftCommunicationsOnline”
},
{
“capabilityStatus”: “Enabled”,
“provisioningStatus”: “Success”,
“service”: “MicrosoftCommunicationsOnline”
},
{
“capabilityStatus”: “Enabled”,
“provisioningStatus”: “Success”,
“service”: “SharePoint”
},
{
“capabilityStatus”: “Enabled”,
“provisioningStatus”: “Success”,
“service”: “SharePoint”
},
{
“capabilityStatus”: “Enabled”,
“provisioningStatus”: “Success”,
“service”: “MicrosoftCommunicationsOnline”
},
{
“capabilityStatus”: “Enabled”,
“provisioningStatus”: “Success”,
“service”: “exchange”
},
{
“capabilityStatus”: “Enabled”,
“provisioningStatus”: “Success”,
“service”: “exchange”
},
{
“capabilityStatus”: “Enabled”,
“provisioningStatus”: “Success”,
“service”: “exchange”
},
{
“capabilityStatus”: “Enabled”,
“provisioningStatus”: “Success”,
“service”: “exchange”
},
{
“capabilityStatus”: “Enabled”,
“provisioningStatus”: “Success”,
“service”: “exchange”
}
]
}

As you notice, there are additional set of properties available. I can group them up in below headings and then they make perfect sense to be present with each user –

  1. Personal Details
  2. Organization details
  3. Subscription SKUs assigned
  4. On-premises Extension attributes
  5. Cloud services provisioned

Looking at the properties available in Graph Beta end point, I can certainly say that based user profiles properties, you can generate content on demand using the properties. This could help in building a better modern workplace personalised to user based on properties value.

Microsoft Flow – JSON Hack with Graph API data

I was working with Flow on a specific scenario and I found some hacks to be played when you are doing JSON parsing and looking to use that data in subsequent actions.

Scenario – I am reading Azure AD users via MS Graph API to keep a list of profile in any other system, let’s say in a SharePoint List.

Solution Approach – Build a Flow which uses Graph API to read all users.
Graph API URL – https://graph.microsoft.com/v1.0/users
To build a Flow with Graph API, please refer to video – Flow With Microsoft Graph API by Ashish Trivedi
SharePoint List setup – Create a custom list with additional columns as defined below

Column Name Column Type
Title Single line of text
First Name Single line of text
Last Name Single line of text
Job Title Single line of text
Display Name Single line of text
User Principal Name Single line of text

Issue(s) – When you hit the API in Graph Explorer (https://developer.microsoft.com/en-us/graph/graph-explorer), you can see the value returned. The same values will be returned in Flow also. Now, when you use action JSON parsing, based on the blog, first returned JSON object is used to template the remaining JSON model. And this is the PROBLEM of FLOW.
Case 1: the first object has all properties, while the next one does not have all properties values. This causes Flow to fail when Flow reads second object. Error Message will appear as ‘”message”: “Invalid type. Expected String but got Null.”‘
Case 2: Now, let’s give the worst case scenario in sample payload to generate the schema for the JSON. When you do that, it parses the JSON well and can read all values. When I did this last night, I was not able to select the parsed JSON properties against SP list item properties. But today while writing this blog, I can’t replicate that. Very good work Flow team.

Case 1: When first object has all property values Case 2: when first object does not have all property values
{
“type”: “object”,
“properties”: {
“@@odata.context”: {
“type”: “string”
},
“value”: {
“type”: “array”,
“items”: {
“type”: “object”,
“properties”: {
“id”: {
“type”: “string”
},
“businessPhones”: {
“type”: “array”,
“items”: {
“type”: “string”
}
},
“displayName”: {
“type”: “string”
},
“givenName”: {
“type”: “string”
},
“jobTitle”: {
“type”: “string”
},
“mail”: {
“type”: “string”
},
“mobilePhone”: {
“type”: “string”
},
“officeLocation”: {},
“preferredLanguage”: {
“type”: “string”
},
“surname”: {
“type”: “string”
},
“userPrincipalName”: {
“type”: “string”
}
},
“required”: [
“id”,
“businessPhones”,
“displayName”,
“givenName”,
“jobTitle”,
“mail”,
“mobilePhone”,
“officeLocation”,
“preferredLanguage”,
“surname”,
“userPrincipalName”
]
}
}
}
}
{
“type”: “object”,
“properties”: {
“@@odata.context”: {
“type”: “string”
},
“value”: {
“type”: “array”,
“items”: {
“type”: “object”,
“properties”: {
“id”: {
“type”: “string”
},
“businessPhones”: {
“type”: “array”
},
“displayName”: {
“type”: “string”
},
“givenName”: {},
“jobTitle”: {},
“mail”: {},
“mobilePhone”: {},
“officeLocation”: {},
“preferredLanguage”: {},
“surname”: {},
“userPrincipalName”: {
“type”: “string”
}
},
“required”: [
“id”,
“businessPhones”,
“displayName”,
“givenName”,
“jobTitle”,
“mail”,
“mobilePhone”,
“officeLocation”,
“preferredLanguage”,
“surname”,
“userPrincipalName”
]
}
}
}
}

Work around –

To use best of both cases, you should apply two steps clean up –

  1. Remove the type value within the properties, so that the Flow does not know what is returned type, text or null.
  2. Remove fields from required section. Just keep the fields like ID which will be present always.

This helped me to get past all hurdles and I can get all User profile values in SP list using Flow.

[I will write about the difference between v1 and beta endpoint of Graph User API endpoint this week. Watch this space.]

WPF Application with Microsoft Graph API

As per my previous blog, we can easily integrate the Graph API in Windows Forms application.

In this article, I am going to select WPF application and connect with Graph API. The purpose of connecting with Graph API is that, it can provide a lot of information and intelligence. Apart from that, if you have Azure AD secured APIs, you can call those APIs using the authentication token. This will help to enable security in your application and service calls.

We are going to use the authentication with Azure AD v2 endpoint, which support authentication from consumer and commercial accounts using same code base. MSAL manages caching and refreshing access tokens for you, so that your application doesn’t need to.

Let’s build the sample step by step.

  1. In Visual Studio, select File > New > Project.Under Templates, select Visual C#.
  2. Select WPF App or WPF Application, depending on the version of Visual Studio version you’re using.
  3. Add MSAL to project by using Microsoft.Identity.Client nuget package including pre-release version.
  4. Adding Code to project –
  5. App.xaml.cs

    using Microsoft.Identity.Client;

    public partial class App : Application{

    private static string ClientId = “your_client_id_here”;

    public static PublicClientApplication PublicClientApp = new PublicClientApplication(ClientId);

    }

  6. MainWindow.xaml

  7. MainWindow.xaml.cs

    using Microsoft.Identity.Client;

    public partial class MainWindow : Window

    {

    string _graphAPIEndpoint = “https://graph.microsoft.com/v1.0/me“;

    string[] _scopes = new string[] { “user.read” };

    public MainWindow()

    {

    InitializeComponent();

    }

    private async void CallGraphButton_Click(object sender, RoutedEventArgs e)

    {

    AuthenticationResult authResult = null;

    try

    {

    authResult = await App.PublicClientApp.AcquireTokenSilentAsync(_scopes, App.PublicClientApp.Users.FirstOrDefault());

    }

    catch (MsalUiRequiredException ex)

    {

    System.Diagnostics.Debug.WriteLine($”MsalUiRequiredException: {ex.Message}”);

    try

    {

    authResult = await App.PublicClientApp.AcquireTokenAsync(_scopes);

    }

    catch (MsalException msalex)

    {

    ResultText.Text = $”Error Acquiring Token:{System.Environment.NewLine}{msalex}”;

    }

    }

    catch (Exception ex)

    {

    ResultText.Text = $”Error Acquiring Token Silently:{System.Environment.NewLine}{ex}”;

    return;

    }

    if (authResult != null)

    {

    ResultText.Text = await GetHttpContentWithToken(_graphAPIEndpoint, authResult.AccessToken);

    DisplayBasicTokenInfo(authResult);

    this.SignOutButton.Visibility = Visibility.Visible;

    }

    }

    }

    public async Task GetHttpContentWithToken(string url, string token)

    {

    var httpClient = new System.Net.Http.HttpClient();

    System.Net.Http.HttpResponseMessage response;

    try

    {

    var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);

    request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(“Bearer”, token);

    response = await httpClient.SendAsync(request);

    var content = await response.Content.ReadAsStringAsync();

    return content;

    }

    catch (Exception ex)

    {

    return ex.ToString();

    }

    }

    private void SignOutButton_Click(object sender, RoutedEventArgs e)

    {

    if (App.PublicClientApp.Users.Any())

    {

    try

    {

    App.PublicClientApp.Remove(App.PublicClientApp.Users.FirstOrDefault());

    this.ResultText.Text = “User has signed-out”;

    this.CallGraphButton.Visibility = Visibility.Visible;

    this.SignOutButton.Visibility = Visibility.Collapsed;

    }

    catch (MsalException ex)

    {

    ResultText.Text = $”Error signing-out user: {ex.Message}”;

    }

    }

    }

    private void DisplayBasicTokenInfo(AuthenticationResult authResult)

    {

    TokenInfoText.Text = “”;

    if (authResult != null)

    {

    TokenInfoText.Text += $”Name: {authResult.User.Name}” + Environment.NewLine;

    TokenInfoText.Text += $”Username: {authResult.User.DisplayableId}” + Environment.NewLine;

    TokenInfoText.Text += $”Token Expires: {authResult.ExpiresOn.ToLocalTime()}” + Environment.NewLine;

    TokenInfoText.Text += $”Access Token: {authResult.AccessToken}” + Environment.NewLine;

    }

    }

The authentication flow of this application is –

Microsoft Graph API – How to use in Windows Forms Application

Microsoft Graph API is not new for developers in the world of Microsoft 365 (Office 365). Please check my previous blog about the summary of Graph API services summary.

As this is an API, you can consume in your supported application in number of ways, either use SDK or use the REST end point of the service.

Challenge-
The latest type of applications where Graph API is used are Office Add-ins, SharePoint Framework components, Microsoft Teams extensions or Office 365 Apps.

Consider if you have a business critical application which is built in Windows Forms or a WPF. That sounds like stone age in current technology world, but there are businesses which are still running on those legacy platforms. The challenge in front of those businesses is that they want to use latest technology without leaving the comfort zone.

Solution –
With new Windows Community Toolkit, a GraphLogin component is being made available to be used in windows form application. This provides an easy to use experience for authenticating with Azure AD and Microsoft Graph.

What is this components – This component wraps the Toolkit’s MicrosoftGraphService for an easy to use login experience. The control then provides read-only properties about the logged on user and instance of GraphServiceClient which can be used for additional call with Microsoft Graph SDK.

Let’s build it –

  1. First make sure that you have .NET Framework equal or higher than 4.6.2. If not, please update the framework based on your VS version.
  2. Select Windows Forms App in VS for creating a new project.

  3. Let’s call solution name as ‘WindowsFormsAppWithGraph’.
  4. Now, next installing the Nuget packages, so that we can get required components in the solution.
    • First add, ‘Microsoft.Toolkit.services’. Current version as of publishing was 3.0.0.0. (I got error that it cannot resolve dependency on Microsoft.Identity.Client nuget package. In that case, I installed it first and then there was no issue).
    • Then install, ‘Microsoft.Toolkit.Win32.UI.Controls’ nuget package.
  5. After successfully installing Nuget packages, let’s add the GraphLoginComponent control in the toolbox pane.
    • Right click in toolbox –> Choose items –> Browse. –> \packages\Microsoft.Toolkit.Services.3.0.0\lib\net461\Microsoft.Toolkit.Services.dll –> Click Ok –> Click Ok.
    • Now, you should see GraphLoginComponent in toolbox.
  6. Let’s add following controls on the form to design the information. Keep all properties as it is else defined below
    • 2 Labels
    • 1 Button
    • 1 picture box [set properties – StretchImage – StretchImage]
    • 1 datagridview
    • 1 GraphLoginComponent

    Form will look like below –

  7. Let’s register the app, so that we have the application id which will be required in code
  8. Let’s add functionality now. Highlighted with yellow boxes in below screen shot –

    Look at the code available at https://github.com/ashuetawah/WindowsFormsAppWithGraph/blob/master/WindowsFormsAppWithGraph/Form1.cs

  9. Let’s run the application
    1. First you will get your login prompt to Office 365

    2. When successfully logged in, you need to consent to permissions.

    3. Once done, you will see the output on page as

  10. In the code, Microsoft.Graph.GraphServiceClient graphClient = graphLoginComponent1.GraphServiceClient; will help you to get other APIs calls straight using GraphClient object.

Please let me know your comments. I will be sharing WPF code with Graph API soon.

Graph API – Summary of services

First thing first, I love Microsoft Graph API and thus it can be a biased blog :).

Microsoft Graph API is becoming the single endpoint entry the Microsoft 365 world. The one and only Microsoft Graph API enables developers to integrate with the best of O365, Windows 10 and Enterprise Mobility and Security services in Microsoft 365. Graph API include security and social intelligence that can boost end user productivity, creativity and team collaboration and data.

I am summarizing the services, and description what includes in Graph API as below –

Features Definition Supporting Services Description Read More More Read
Users A user in Microsoft Graph is one among the millions who use M365 service. Azure AD and The user is a core focus of MS Graph, around which many Microsoft Graph services build user-centric functionality. It is the focal point whose identity and access are well managed. Overview of users in Microsoft Graph
Groups An O365 Group is the fundamental entity that lets users collaborate. It integrates with other services, enabling richer scenarios in task planning, teamwork and more. Azure AD, OneDrive, OneNote, Outlook, Planner An Office 365 group provides the fundamental collaborative unit for users to share conversations, files, notes, calendar, plans, and more. Overview of Office 365 groups in Microsoft Graph

Most of the services focus around users and groups. Graph forms a network of M365 services and features that manages, protect and extract data to support range of scenario.

Features Description Supporting Services More Read
Identity and access management Creates and manages directory resources as users, groups, apps. Manage access to resources and data. Azure AD Azure AD identity and access management overview
Calendar Lets user setup appointments and meetings on the web, mobile and desktop devices. It is part of Outlook messaging in O365. Outlook Outlook calendar overview
Files Manages and shares user files on OD and SP. OneDrive

SharePoint

OneDrive files storage overview
Mail Lets user communicate, organize and manage priorities in messages in their workflows on any device. Outlook Outlook mail overview
Notes Lets user plan and organize ideas and information OneNote OneNote notes overview
Personal Contacts Contacts manager on the web/mobile/desktop. It is part of Outlook messaging. Outlook Outlook personal contacts overview
Workbooks and Charts Lets user use excel spreadsheets to do complex calculations, track, analyse and visualise data and generate professional reports. Excel Excel workbooks and charts overview
Sites and Lists Web-based platform for users to share, organize, manage and discover content including lists, files and notes SharePoint SharePoint sites and content overview
Tasks and plans Enable users in O365 groups to create plans, assign tasks and track progress Planner Planner plans and tasks overview
Teamwork Digital hub and chat-based workspace for teams to share files, notes, calendar and plans Microsoft Teams Microsoft Teams teamwork overview
Social Intelligence: People Gets info about person as ordered by their relevance to a user, determined by user’s communication and collaboration patterns and business relationship. Azure AD

SharePoint

Outlook

Social intelligence in Microsoft Graph
Social Intelligence: Document insights Uses advanced analytics and machine learning techniques to get documents trending around, viewed, modified or shared by a user Delve, OneDrive, SharePoint, Outlook Social intelligence in Microsoft Graph
Devices and apps Enrol and configure devices and manages mobiles apps in your organization Intune Intune devices and apps overview
Security Integration Provides a unified gateway to security insights and actions across Microsoft and ecosystems partners. Azure AD Identity Protection, Azure Security Centre Security in Microsoft Graph
Identity protection Gives access to sign-in and account risk data for users in Azure AD Azure AD Security in Microsoft Graph
Cross-device experiences Enables app experiences that transcend a single device and instead move with the user from device to device regardless of its type and platform. Activity feed, device relay Overview for cross-device experiences
Reports Gets activity and usage information of a supporting service. Microsoft Teams, OneDrive, Outlook, SharePoint, Skype for business, Yammer Usage reports overview
Education Provides information relevant for education scenarios including school, classes, students, teachers and assignment info. Enables ISVs to build applications for the classroom that save teachers time and promote teamwork and collaboration. Azure AD, Education Education overview
Customer Booking Target small businesses to enable their customers to book services directly on the web or Facebook. Lets business operators manage customers preferences, services and pricing, staff list and schedules. Microsoft Bookings Microsoft Bookings API overview
At the end, I will just say that there are enormous opportunities are available with Graph API. It’s up to us to use it.

 

SPFx – Web Part capabilities

Webparts are very important component in SharePoint (be in Online or on-premises). Webparts are building blocks of the pages that appear on SharePoint site.

Using SPFx based client-side web parts on modern script platforms, you can deploy them to modern and classic web part pages in SharePoint.

History –

Webparts are available from SharePoint 2007 onwards as part to support the extensibility from ASP.NET Web part class. They served different purpose that time. Since then there has been various ways to use the web parts. Few common scenarios which I know are –

  • Server-side web part
  • Web part using custom control as visual web part
  • Client-side web part in SharePoint
  • Connecting two web parts on same page
  • Configuration driven web parts using web part properties.
  • Simple webparts in content/script editor web parts.

SPFx is slowly and steadily taking over all the scenarios and making sure that this can replace all possible cases where developers had used old web part approach.

Let’s understand if SPFx can match all my requirements and can help me to upgrade my legacy web parts to SPFx.

What’s current –

The current SPFx toolchain and framework capability allows developers to build modern demand-based solutions. I am going to write about specific base class, interface or about how to write it. All the required information is written well in Microsoft document which is available at the URL https://docs.microsoft.com/en-us/sharepoint/dev/spfx/sharepoint-framework-overview.

I am going to write the capabilities in grouped points so that you can refer them easily.

  • Getting Started –
    • You can build web part using modern open source toolchain which can support either of popular JS framework to develop your web part.
    • Your web part now can be developed offline and don’t require SharePoint to be installed locally. When you are ready you can test web part directly without deploying in live environment by running them from localhost.
    • As SPFx include a lot of script & style files, you can deploy the artefacts to a CDN (Office 365, Azure or local) of your choice.
    • To support building native solution design and branding, Office UI Fabric is natively integrated with SPFx. You can use branding or even React based controls to be included in the SPFx web part.
    • As part of feature deployment of webpart, you might have provisioned lists/site columns/content types. In the SPFx also, you can create XML files to create site columns/content types/lists (define using List schema).
  • Basics –
    • The web parts were popular because you can configure them using properties. In SPFx based webparts also you can have properties and these properties can read information from SharePoint context.
    • The properties of web part can be well defined that you can have custom controls in property pane. And, the configuration of web part can be of multiple pages.
    • The properties can be set to default values. So, when user add this web part to page, the functionality uses default value to render UI. You can create multiple instances of the web part with different default values to save time and enable users to use the pre-configured webparts directly.
    • When you use property pane to provide configuration to your web part, you must validate those properties before using them. SPFx provide mechanism to validate properties and provide necessary error messages to end user.
    • One of the cool feature of web parts is that you can share data between two web parts available on same page. SPFx also supports that. Thus, enable you to create connected components.
    • As said above, you can add controls to SPFx web part property pane, which also support custom controls in the property pane.
    • Other legacy customizations like script editor web part, Angular JS applications, JSOM and jQuery related applications can be migrated to SPFx model easily.

    I will keep this to focused on web part specific features. In next one, you will get summary of extensions.