Powered By Blogger

Friday, December 22, 2023

Power Apps Portal - Retrieve Data using Portal Web API

With the more recent versions of the PowerApps Portals, we now have the ability to utilize Portals Web APIs. There are some limitations and requirements around this, however, it allows us to use CRUD operations directly from JS. You can find out about this here: https://learn.microsoft.com/en-us/power-pages/configure/web-api-overview

Here, as an example, I will show you how to retrieve single record using Portal Web API. It's important to know below:

1. That your portal version must be 9.3.3.x or later for this feature to work.

2. You need to enable the site settings for the particular entity you are going to retrieve from the Dataverse.


Web API URL and versioning

Construct the Web API URL by using the format in the following table.

For example, use this format when referring a case:

https://contoso.powerappsportals.com/_api/case

All Web API resources will follow the respective table permissions in context with web roles.


HTTP methods

HTTP requests can use different kinds of methods. However, the portals Web API only supports the methods in the following table:


HTTP headers

The Web API only supports JSON. Each HTTP header must include:

An Accept header value of application/json, even when no response body is expected.
If the request includes JSON data in the request body, you must include a Content-Type header with a value of application/json.

Example:

Firstly, We need to add the "Wrapper AJAX function for the CSRF token". For this, You need to create a New Web Template:

First Web Template - WebAPIAjax

<script>
(function(webapi, $){
        function safeAjax(ajaxOptions) {
            var deferredAjax = $.Deferred();
    
            shell.getTokenDeferred().done(function (token) {
                // add headers for AJAX
                if (!ajaxOptions.headers) {
                    $.extend(ajaxOptions, {
                        headers: {
                            "__RequestVerificationToken": token
                        }
                    });
                } else {
                    ajaxOptions.headers["__RequestVerificationToken"] = token;
                }
                $.ajax(ajaxOptions)
                    .done(function(data, textStatus, jqXHR) {
                        validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve);
                    }).fail(deferredAjax.reject); //AJAX
            }).fail(function () {
                deferredAjax.rejectWith(this, arguments); // on token failure pass the token AJAX and args
            });
    
            return deferredAjax.promise();  
        }
        webapi.safeAjax = safeAjax;
    })(window.webapi = window.webapi || {}, jQuery)
</script>


Now, you need to create a second new web template to retrieve data from the Dataverse via JS that consumes the above wrapper AJAX function to call the web API.

Second Web Template - Get Data from Dataverse

{% assign title = 'My Second Web Template to Consume Web API' %}
{% include 'WebAPIAjax' %}

<div class="container">
<div class="page-heading">
{% block breadcrumbs %}
{% include 'Breadcrumbs' %}
{% endblock %}
</div>
<div class="row">
{% block title %}
<h2><b>{{title}}</b></h2>
{% endblock %}
</div>
</div>

<script>
  function getData() {
    try {
      var Id= "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";            
      var webApiUrl = "/_api/entityName(" + Id + ")?$select=attr1";
      var attr1Val = getResponse(webApiUrl).attr1;
    }
    catch (error) {
      alert("Error!" + error);
    }
  }

  function getResponse(webApiUrl) {
    var response = null;
    webapi.safeAjax({
      type: "GET",
      url: webApiUrl,
      contentType: "application/json",
      async: false,
      success: function (res) {
        response = res;
      },
    });
    return response;
  }
</script>

So, here getResponse(webApiUrl) method will connect to the Web API using the above Wrapper AJAX Function and get the data from the Dataverse. It will return the entire response in JSON format and since, we have only selected "attr1" in the query, it will return only that attribute in the response and for fetching multiple attributes, you just need to pass all those attributes in the "select" parameter in the URL (Note: Don't forget to enable, all those fields in the Web API site settings otherwise it won't be able to retrieve it.).

Likewise, you can perform the other operations as well like below:

CREATE:

webapi.safeAjax({
type: "POST",
url: "/_api/accounts",
contentType: "application/json",
data: JSON.stringify({
"name": "Sample Account"
}),
success: function (res, status, xhr) {
console.log("entityID: "+ xhr.getResponseHeader("entityid"))
}
});

UPDATE:

webapi.safeAjax({
type: "PATCH",
url: "/_api/accounts(00000000-0000-0000-0000-000000000001)",
contentType: "application/json",
data: JSON.stringify({
"name": "Sample Account - Updated"
}),
success: function (res) {
console.log(res);
}
});

DELETE:

webapi.safeAjax({
type: "DELETE",
url: "/_api/accounts(00000000-0000-0000-0000-000000000001)",
contentType: "application/json",
success: function (res) {
console.log(res);
}
});


No comments:

Post a Comment

Tools for Unit Testing in Power Platform