{"content":"Dataverse Custom APIs are a powerful extension model of the PowerPlatform. However, at the time of writing, there are no direct method to execute a Custom API inside the PowerApps Canvas App model.\nIn this post I will show how to call any Custom API from a Canvas App with the use of a generic Power Automate Flow and the new ParseJSON functionality.\nUPDATE 17-FEB-2023\nDataverse Custom APIs can now be called directly from PowerFx in Canvas Apps and Custom Pages. ( still in experimental phase)\nCall Dataverse actions directly in Power Fx | Microsoft Power Apps\nCustom APIs in context First off, I have to admit that I am die-hard fan of Dataverse Custom APIs since their introduction. The main reason is that it gives developers a way to use the same endpoint that the platform uses for the core functionalities (CRUD on the data tables etc..) and extend it with tailor-made messages that encapsulates server-side business logic over REST API requests.\nAs a result, the Custom APIs are agnostic to the caller and the same logic can be consumed from different sources like Dataverse plugins, Power Automate flows, model driven forms javascript, PCF controls, external programs etc\u0026hellip;\nSadly, one of the blind spot is the direct use of Custom APIs within a Canvas Apps (or from the new Custom Pages) model. Let\u0026rsquo;s see how we can overcome this limitation in an indirect manner.\nLearn more about Dataverse Custom APIs here: 👉Create and use Custom APIs (Microsoft Dataverse) - Power Apps | Microsoft Learn\nDon\u0026rsquo;t forget to use my Custom API Manager tool for XrmToolBox for great authoring experience : 👉Dataverse Custom API Manager · XrmToolBox\nPrerequisites Follow these steps to setup the stage.\nEnable ParseJson The technique that I will show uses the Canvas Apps ParseJSON function that is still in preview, so the activation of the feature in the settings of the canvas app (or custom page) is required.\nsee the official documentation on the feature here 👉ParseJSON function in Power Apps (experimental) - Power Platform | Microsoft Learn\nInstall the PowerApps.Action.Runner solution (optional) You can follow along and create your own Power Automate flows. But I have created a solution that contains the 2 Power Automate Flows shown later on.\nPowerApps:BoundActionRunner PowerApps:UnboundActionRunner Here\u0026rsquo;s the link to the github repo for download : 👉drivardxrm/PowerApps.Action.Runner: Generic Power Automate Flows to run Dataverse Custom APIs an Actions in Canvas Apps (github.com)\nSurface the Flows in the Canvas Apps Once the Power Automate Flows are installed, they need to be added to the Canvas App being edited by enabling them in the PowerAutomate pane of the Canvas App editor.\nMore on using PowerAutomate flows in a Canvas Apps 👉Use Power Automate pane - Power Apps | Microsoft Learn\nHave some Custom APIs at hand You can use any Custom API from your environment, but for the purpose of the demo, I will showcase 2 Custom APIs that can be found in my generic Dataverse Custom API collection.\nHere\u0026rsquo;s the link to the github repo for download : 👉drivardxrm/Dataverse-CustomApis: Collection of Dataverse Custom Apis (github.com)\nFor the Unbound Custom API example, I will use driv_GetTableInfo. This API takes for input a Dataverse table name (LogicalName) and return a collection of valuable information (metadata) on the table.\nFor the Bound Custom API example, I will show a Custom API bound to the systemuser table driv_GetUserTimezone. This API retrieves the Timezone of a given user from the user personal settings. It can be useful for datetime calculations.\nCalling an unbound Custom API Let\u0026rsquo;s start by presenting a Power Automate flow that can be used to call any unbound Custom APIs, PowerApps:UnboundActionRunner.\nIn fact the flow is quite simple and is merely a wrapper around the Custom API call. It consists of 3 parts, the trigger, the action and the response.\nThe Trigger The flow is of type Instant/PowerApps and this type of trigger is what enables the PowerAutomate flow to be surfaced in the Canvas Apps editor as we seen before.\nThe configuration of the trigger defines 2 input parameters that will be supplied by the calling Canvas App\nActionName : this expects the unique name of the Custom API InputJson : this expects a string in JSON format that contains the request parameters (inputs) one wishes to pass to the Custom API. The Action The action uses the Perform an unbound action that is part of the Power Automate Dataverse connector.\nThe Action Name selector exposes a list of all existing Custom API (and legacy Custom Actions) available in the environment, but in our case we\u0026rsquo;ll just select Enter custom value and affect the ActionName value defined earlier in the trigger.\nNow, since the ActionName is dynamic and will only be resolved at runtime, the Power Automate engine cannot determine the individual input parameters so it shows an input field called Action Parameters that expects a JSON construct representing the input parameters of the API.\nFor example to call the GetTableInfo API on the account Table, the Action Parameters would look something like this\n{ \u0026#39;LogicalName\u0026#39; : \u0026#39;account\u0026#39; } The idea here is to set the Action parameters field with the InputJson received from the trigger. However, it\u0026rsquo;s really important here to convert the InputJson text value using the json() function otherwise an error will be thrown at runtime.\nThe Response To pass the Custom API results back to the calling Canvas Apps, the flow makes use of the Respond to PowerAppp or flow action. Here, Simply set the value of OutputJson property to the response of the Custom API call made earlier.\noutputs(\u0026#39;Perform_an_unbound_action\u0026#39;)?[\u0026#39;body\u0026#39;] Calling the flow from a Canvas App Now to the main event, let\u0026rsquo;s connect the dots and use the Flow inside a Canvas App (or Custom Page) to execute a Custom API.\nThe app shown takes a table name as input and at the click of the button, the PowerApps:UnboundActionRunner is used to execute the GetTableInfo Custom Api and output some metadata information on the form.\nThe OnSelect action of the button is used to set the value of the variable TableInfoResults. The value is the OutputJson resulting from the execution of PowerApps:UnboundActionRunner where the ActionNameand InputJson of the Custom API are supplied. So on every click to the button the flow is executed, the Custom API is called and the expression is re-evaluated based on the value of the textbox.\nSet(TableInfoResults, \u0026#39;PowerApps:UnboundActionRunner\u0026#39;.Run( \u0026#34;driv_GetTableInfo\u0026#34;, \u0026#34;{\u0026#39;LogicalName\u0026#39; : \u0026#39;\u0026#34; \u0026amp; txtInputTable.Value \u0026amp; \u0026#34;\u0026#39;}\u0026#34; ).outputjson) The new ParseJSON() function is applied on the TableInfoResults variable to display the API results on the form. This will deserialize de output of the API response and expose its properties. Here, it\u0026rsquo;s important to cast the desired property to its correct object type (string = Text, number = Value etc..). (See the ParseJSON official docs)\nAs you can see below, the Custom API is being executed on each click of the button and the results are parsed and displayed on the form.\nCalling a bound Custom API To call a bound Custom API we will use the PowerApps:BoundActionRunner from my solution. The idea is the same as the unbound api version so I will not repeat everything.\nThe main differences are at the trigger level as more input parameters are expected.\nTableCollectionName: Collection Name of the Table (normaly the plural name) RecordId: uniqueidentifier (GUID) of the bound record ActionName : this expects the unique name of the Custom API InputJson : this expects a string in JSON format that contains the request parameters (inputs) one wishes to pass to the Custom API. There\u0026rsquo;s also a minor difference in the way that the Action Name needs to be set on the Perform bound action step ( Microsoft.Dynamics.CRM.{ActionName}).\nCalling the flow from a Canvas App For this demo, the button click will call the GetTimezoneInfo Custom API using the current user as the bound record.\nAgain, a variable is set (UserTimezoneResults) with the OutputJson received from the PowerApps:BoundActionRunner flow. The\nSet(UserTimezoneResults, (\u0026#39;PowerApps:BoundActionRunner\u0026#39;.Run( \u0026#34;systemusers\u0026#34;, First(Filter(Users,\u0026#39;PrimaryEmail\u0026#39;=User().Email)).User, \u0026#34;driv_GetUserTimezone\u0026#34;, \u0026#34;\u0026#34;) .outputjson)) The same principle as earlier is applied to Parse the response of the flow and display the results on the form.\nAs you can appreciate, whenever the button is clicked the Custom API will be executed accordingly.\nTakeaway As cool as this is, I have to admit that I hope that this solution will have a short lifespan. It would be great if Custom APIs could be surfaced and executed directly inside Canvas Apps and Custom Pages.\nIn my opinion, the fact that we have to delegate the Custom API call to a PowerAutomate wrapper adds an unnecessary layer of complexity that can affect performance and maintainability.\nAlso, an important point to consider is the concurency on the flow and the API call limit. Since the flows are using a common connection to the Dataverse environment, this means that the same connection will be used for each execution. So if you have several apps used by hundreds of users all using the same flows and connections, you might run into problems down the road.\nBut hey, on the bright side of things let\u0026rsquo;s celebrate that with this solution Custom APIs can be unleashed in the realm of Canvas Apps. I see a lot of use cases for this.\nLinks ParseJSON function in Power Apps (experimental) - Power Platform Reference information including syntax and examples for the ParseJSON function in Power Apps. learn.microsoft.com Dataverse Custom API Manager · XrmToolBox Management tool that provides 360° View of Dataverse Custom APIs. Provides CRUD operations on Custom API, Request Parameters (Inputs) and Response Properties (Outputs). www.xrmtoolbox.com GitHub - drivardxrm/Dataverse-CustomApis: Collection of Dataverse Custom Apis Collection of Dataverse Custom Apis. Contribute to drivardxrm/Dataverse-CustomApis development by creating an account on GitHub. github.com GitHub - drivardxrm/PowerApps.Action.Runner: Generic Power Automate Flows to run Dataverse Custom APIs an Actions in Canvas Apps Generic Power Automate Flows to run Dataverse Custom APIs an Actions in Canvas Apps - GitHub - drivardxrm/PowerApps.Action.Runner: Generic Power Automate Flows to run Dataverse Custom APIs an Actio... github.com Photo by Pavan Trikutam on Unsplash\n","date":"2022-10-31T04:01:32Z","image":"/how-to-call-a-dataverse-custom-api-from-a-canvas-app/pavan-trikutam-71CjSSB83Wo-unsplash-scaled.jpg","permalink":"/how-to-call-a-dataverse-custom-api-from-a-canvas-app/","title":"How to Call a Dataverse Custom API from a Canvas App"}