{"id":4533,"date":"2020-05-04T08:11:50","date_gmt":"2020-05-04T15:11:50","guid":{"rendered":"https:\/\/officedevblogs.wpengine.com\/?p=4533"},"modified":"2021-08-31T14:39:42","modified_gmt":"2021-08-31T21:39:42","slug":"a-lap-around-microsoft-graph-toolkit-day-7-microsoft-graph-toolkit-providers","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/a-lap-around-microsoft-graph-toolkit-day-7-microsoft-graph-toolkit-providers\/","title":{"rendered":"A Lap around Microsoft Graph Toolkit Day 7 \u2013 Microsoft Graph Toolkit Providers"},"content":{"rendered":"<p><strong>Author:<\/strong> Simon \u00c5gren, Microsoft Office Development MVP<\/p>\n<p>Welcome to Day 7 of the <a href=\"https:\/\/aka.ms\/mgtlap\">Microsoft Graph Toolkit blog series<\/a>!<\/p>\n<p>So far in this series, you have gotten acquainted with many important pieces of the Microsoft Graph Toolkit. Today we will talk about the last remaining piece of the puzzle, the piece that makes everything magically work \u2013 the provider.<\/p>\n<p>The fundamental role of a Microsoft Graph Toolkit provider is to enable all the components to call Microsoft Graph to retrieve and render data. The provider takes care of getting the necessary access token with the requested scopes.<\/p>\n<p>Today you will get a high-level overview of the Microsoft Graph Toolkit Providers, the architecture and even how we could use it outside of the components to make Microsoft Graph calls.<\/p>\n<h3>What\u2019s in the box?<\/h3>\n<p>Microsoft Graph Toolkit offers ready-to-go providers that are useful in the most common scenarios.<\/p>\n<p>Providers\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Description<\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/toolkit\/providers\/msal\">Msal<\/a>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Uses MSAL.js to sign in users and acquire tokens to use with Microsoft Graph.<\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/toolkit\/providers\/sharepoint\">SharePoint<\/a> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Authenticates and provides Microsoft Graph access to components inside of\u00a0 SharePoint web parts.<\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/toolkit\/providers\/teams\">Teams<\/a>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Authenticates and provides Microsoft Graph access to components inside of Microsoft Teams tabs.<\/p>\n<p><a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/toolkit\/providers\/proxy\">Proxy<\/a>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Allows the use of backend authentication by routing all calls to Microsoft Graph through your backend.<\/p>\n<h3>Custom Provider<\/h3>\n<p>All the ready-to-go Microsoft Graph Toolkit providers have been created in the same way that you could create providers yourself. They are reusable and are created for the most common scenarios. When would you create your own custom provider then?<\/p>\n<p>You\u2019d want to create your own provider if you find yourself in a scenario where you have an application with existing authentication code and want to hook into that mechanism. The question you want to ask yourself here is if it makes sense to create a reusable provider. Is this likely a recurrent situation? If the answers are yes, you are at the right spot to learn how to create your own providers. There are two ways to create custom providers:<\/p>\n<h4>SimpleProvider<\/h4>\n<p>For non-recurrent situations you can use the simple provider. Basically, the role of the simple provider is to return the token from your own authentication code. Instantiate a <strong>SimpleProvider <\/strong>class by passing in a function that will return an access token for passed-in scopes.<\/p>\n<p>Here is a sample that <a href=\"https:\/\/twitter.com\/metulev\">Nikola Metulev<\/a> built with the SimpleProvider and MSAL.js: <a href=\"https:\/\/github.com\/microsoftgraph\/microsoft-graph-toolkit\/blob\/master\/samples\/examples\/simple-provider.html\">Simple Provider Sample<\/a><\/p>\n<h4>IProvider<\/h4>\n<p>For resusability in recurrent situations you can create your own provider. All Microsoft Graph Toolkit Providers (including SimpleProvider) extend the <strong>IProvider <\/strong>abstract class. You can also extend <strong>IProvider <\/strong>to create your own provider.\u00a0 We suggest you read more here: <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/toolkit\/providers\/custom#iprovider\">IProvider Documentation<\/a><\/p>\n<h4>The Architecture<\/h4>\n<p><img decoding=\"async\" class=\"alignleft wp-image-4545 size-full\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Picture1.png\" alt=\"architecture diagram for Microsoft Graph Toolkit providers. \" width=\"893\" height=\"502\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Picture1.png 893w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Picture1-300x169.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Picture1-768x432.png 768w\" sizes=\"(max-width: 893px) 100vw, 893px\" \/><\/p>\n<p>The image above is an attempt to visualize the Microsoft Graph Toolkit provider architecture at a high level. The image is divided vertically into two sections: <strong>Provider Initialization<\/strong> and <strong>Provider Consumption<\/strong>. There is actually more going on behind the scenes than shown in this diagram &#8211; these are the important things to understand.<\/p>\n<p>The <strong>Providers<\/strong> namespace is very central, as it holds the global provider reference that is being used by the components when calling Microsoft Graph.<\/p>\n<h4>Provider Initialization<\/h4>\n<p>The first thing we need to do is initialize a new provider. Then we need to set the newly initialized provider as the \u201cglobal provider\u201d in the Providers namespace. You can do this process in two distinct ways.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Image-2.jpg.png\"><img decoding=\"async\" class=\"alignleft wp-image-4535 size-full\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Image-2.jpg.png\" alt=\"top portion of providers architecture where it shows provider initialization\" width=\"1724\" height=\"611\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Image-2.jpg.png 1724w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Image-2.jpg-300x106.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Image-2.jpg-1024x363.png 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Image-2.jpg-768x272.png 768w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Image-2.jpg-1536x544.png 1536w\" sizes=\"(max-width: 1724px) 100vw, 1724px\" \/><\/a><\/p>\n<h4>By a developer in code<\/h4>\n<p>Simple enough, we initialize a new provider instance with the configuration properties we need and set it to be the global provider.<\/p>\n<pre class=\"lang: decode:true\">Providers.globalProvider = new MsalProvider({\r\n\u00a0\u00a0\u00a0 ClientId: \u2018[CLIENT_ID]\u2019\r\n});<strong>\u00a0<\/strong><\/pre>\n<p>Another example could be in a SharePoint Framework Web Part, where we use the Web Part Context to initialize a new <strong>SharePointProvider<\/strong>.<\/p>\n<pre class=\"lang: decode:true\">protected async onInit() {\r\n\u00a0\u00a0\u00a0 Providers.globalProvider = new SharePointProvider(this.context);\r\n}<\/pre>\n<h4>Using a Component Provider<\/h4>\n<p>In the last post regarding the <a href=\"https:\/\/developer.microsoft.com\/en-us\/graph\/blogs\/a-lap-around-microsoft-graph-toolkit-day-6-the-power-of-mgt-get\/\"><strong>The Power of mgt-get<\/strong><\/a> you saw the usage of the Component Provider <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/toolkit\/providers\/msal\"><strong>mgt-msal-provider<\/strong><\/a>.<\/p>\n<pre class=\"lang: decode:true\">&lt;mgt-msal-provider client-id=\u201d[CLIENT_ID]\u201d&gt;&lt;\/mgt-msal-provider&gt;<\/pre>\n<p>Behind the scenes the component provider initializes a provider in code and sets it as the Global Provider, in a similar fashion as the developer would have done.<\/p>\n<pre class=\"lang: decode:true\">this.provider = new MsalProvider(config);\r\nProviders.globalProvider = this.provider;<\/pre>\n<h4>Provider Consumption<\/h4>\n<p>Microsoft Graph Toolkit uses the <a href=\"https:\/\/github.com\/microsoftgraph\/msgraph-sdk-javascript\">Microsoft Graph JavaScript SDK<\/a> for all calls to Microsoft Graph. The IProvider has been designed to work with the SDK and its AuthenticationProvider class.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Picture2.png\"><img decoding=\"async\" class=\"wp-image-4546 size-full aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Picture2.png\" alt=\"bottom portion of providers architecture where it shows provider consumption\" width=\"750\" height=\"256\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Picture2.png 750w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/Picture2-300x102.png 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/a><\/p>\n<p>Each provider implements an instance of the SDK which enables the provider to call Microsoft Graph APIs either from inside of a component or outside. More on this later\u2026<\/p>\n<p>Another cool thing is that the provider keeps track of the user\u2019s authentication state, which is either <strong>loading<\/strong>, <strong>SignedIn <\/strong>or <strong>SignedOut<\/strong>. When the state changes the components gets an update via event handlers, so they know when it&#8217;s time to call the Graph.<\/p>\n<p>Each component checks to see if there&#8217;s a provider present and if the state is <strong>SignedIn <\/strong>before using the SDK to call the Graph.<\/p>\n<pre class=\"lang: decode:true\">if (provider &amp;&amp; provider.state === ProviderState.SignedIn) {\r\n\u00a0\u00a0\u00a0 const graph = provider.graph.forComponent(this);\r\n}<\/pre>\n<h3>Extending the mgt-get scenario<\/h3>\n<p>In the previous post <a href=\"https:\/\/twitter.com\/CameronDwyer\">Cameron Dwyer<\/a> created a great scenario in order to show you how to use <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/toolkit\/components\/get\">mgt-get<\/a> to displaying items from a SharePoint list. But what if we would like to do another operation that is not about getting data, what if we want to create or update something?<\/p>\n<p>We will build upon the scenario from the previous post, by grabbing the initialized global provider from the Providers namespace and use it to update the list items in the SharePoint list.<\/p>\n<p>Let\u2019s look at some of the code&#8230; (You can also look at this sample in <a href=\"https:\/\/github.com\/microsoftgraph\/mgtLap-TryItOut\/blob\/master\/07%20-%20Providers\/index.html\">Try-It-Out repo here<\/a>.)<\/p>\n<pre class=\"lang: decode:true\">const provider = mgt.Providers.globalProvider;\r\nlet graphClient;\r\nif (provider &amp;&amp; provider.state === mgt.ProviderState.SignedIn) {\r\n\u00a0\u00a0\u00a0 graphClient\u00a0 = provider.graph.client;\r\n}<\/pre>\n<p>After grabbing the Global Provider, we check the state to see if the user is considered signed in. If that is the case, we create a reference to the SDK Graph Client.<\/p>\n<p>I have made some small changes to the HTML code as well:<\/p>\n<p><img decoding=\"async\" class=\"alignleft wp-image-4537\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-4-1024x515.png\" alt=\"code block that uses mgt-get to build the packing app.\" width=\"925\" height=\"465\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-4-1024x515.png 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-4-300x151.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-4-768x386.png 768w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-4.png 1070w\" sizes=\"(max-width: 925px) 100vw, 925px\" \/><\/p>\n<ul>\n<li>The $filter includes all that aren\u2019t \u2018Delivered\u2019<\/li>\n<li>I have created a status span that depending on status displays a different color<\/li>\n<li>If the item status is \u2018Requested\u2019 (not Packed) I display a button that lets the user \u201cPack\u201d it.<\/li>\n<\/ul>\n<p>This is how it looks like now.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-5.png\"><img decoding=\"async\" class=\"aligncenter wp-image-4538 size-full\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-5.png\" alt=\"UI with updated functionality that a user can choose to pack an unfulfilled order.\" width=\"746\" height=\"629\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-5.png 746w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-5-300x253.png 300w\" sizes=\"(max-width: 746px) 100vw, 746px\" \/><\/a><\/p>\n<p>If the user would click the \u201cPack\u201d button we would run the <strong>updateOrder() <\/strong>function in the background:<\/p>\n<p><img decoding=\"async\" class=\"alignleft wp-image-4539\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-6-1024x230.png\" alt=\"code block to update UI and data where orders are fulfilled.\" width=\"903\" height=\"202\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-6-1024x230.png 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-6-300x67.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-6-768x172.png 768w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-6.png 1417w\" sizes=\"(max-width: 903px) 100vw, 903px\" \/><\/p>\n<p>This function is in charge of updating the specified list item in SharePoint. It takes two arguments in the constructor: <strong>orderId <\/strong>(string) and <strong>newStatus <\/strong>(string), and then makes an <strong>update()<\/strong> (PATCH) call. I\u2019m using the <strong>prepScopes<\/strong> from Microsoft Graph Toolkit in order to utilize the correct scope for the operation.<\/p>\n<p>When the update is done, you\u2019ll get a notification indicating that the packing of the item went well.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-7.png\"><img decoding=\"async\" class=\"aligncenter wp-image-4540 size-full\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-7.png\" alt=\"UI notification when order is packed\" width=\"775\" height=\"290\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-7.png 775w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-7-300x112.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-7-768x287.png 768w\" sizes=\"(max-width: 775px) 100vw, 775px\" \/><\/a><\/p>\n<p>And lastly, the order with the status \u2018Requested\u2019 is now considered packed.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-8.png\"><img decoding=\"async\" class=\"aligncenter wp-image-4541 size-full\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-8.png\" alt=\"UI of SharePoint List changes when order is packed.\" width=\"731\" height=\"615\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-8.png 731w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2020\/05\/image-8-300x252.png 300w\" sizes=\"(max-width: 731px) 100vw, 731px\" \/><\/a><\/p>\n<h3>Finishing up<\/h3>\n<p>Today we have focused on Microsoft Graph Toolkit providers. You have seen an overview of how to use out-of-the-box Microsoft Graph Toolkit providers, gotten some ideas on when and how to create your own, and how easy it is to use the Graph Client (Microsoft Graph JavaScript SDK) outside of the components.<\/p>\n<p>The whole idea behind the Microsoft Graph Toolkit is to make it faster and easier for developers\u00a0 to create and customize many of the most commonly used\u00a0 components in Microsoft 365 apps and integrations &#8211; without having to focus too much on what is happening behind the scenes.<\/p>\n<p>After today we hope that you understand that you have even more options with Microsoft Graph Toolkit, to call Microsoft Graph in your own preferred way, as the last remaining piece of the puzzle.<\/p>\n<h3>Build 2020 and Season 2<\/h3>\n<p>Look for us at Build 2020 where we\u2019ll do a session on Microsoft Graph toolkit for beginners. If you would like to code with us, we will also host a live coding session using Microsoft Graph Toolkit and show you how to build apps that are connected to Microsoft Graph in the most efficient way! We will resume our blog series on June 1<sup>st<\/sup> for season 2 of A Lap around Microsoft Graph Toolkit. We have articles on each provider accompanied by more samples. Let us know what you think on social network using #MSGraphToolkitLap! See you soon.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Welcome to Day 7 of the Microsoft Graph Toolkit blog series! Today we will talk about the last remaining piece of the puzzle, the piece that makes everything magically work \u2013 the provider.<\/p>\n","protected":false},"author":69077,"featured_media":25159,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3],"tags":[34],"class_list":["post-4533","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-graph","tag-microsoft-graph-toolkit"],"acf":[],"blog_post_summary":"<p>Welcome to Day 7 of the Microsoft Graph Toolkit blog series! Today we will talk about the last remaining piece of the puzzle, the piece that makes everything magically work \u2013 the provider.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/4533","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/users\/69077"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/comments?post=4533"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/4533\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media\/25159"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media?parent=4533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/categories?post=4533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/tags?post=4533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}