February 14, 2022

Dataverse REST Builder and FetchXML

In the last version of DRB I just published (1.0.0.31) I added a new tab FetchXML for the Retrieve Single and Retrieve Multiple request types:

You can't create a 1 to 1 conversion between Web API and FetchXML because the two query languages are not compatible (meaning you can usually do more stuff with FetchXML) but it's possible to convert some queries (FetchXML Builder has the option to export to Web API for a while now).

To be honest adding the FetchXML tab to DRB was only an exercise for me (and the generated code can be improved), I don't think someone will use my tool to generate FetchXML when there is FetchXML Builder (I am also an avid user of the tool).

However it allowed me to refresh a bit the FetchXML syntax and more important dealing with two aspects inside the XrmToolBox version:
  • Sending information from the web page to the container hosting the WebView2 component
  • Use the integration between tools offered by the IMessageBusHost interface
The first can be done using chrome.webview.postMessage from the web page and listening to the event WebMessageReceived inside the container.

The second utilizes the OnOutgoingMessage event, my friend Jonas Rapp wrote a page with some examples: Integrate with FetchXML Builder

If you are curious on how these things work you can check the code from this repository.

Leveraging this code, DRB can send the FetchXML code to FetchXML Builder when is executed inside XrmToolBox:
hope it helps!


January 24, 2022

Relationship Columns added to DRB filter

I admit I recently "spammed" Dataverse REST Builder when I answer questions regarding Dataverse Web API, often an error is related to the code syntax or to the query (especially when dealing with navigation properties) so having a tool to generate the syntax is useful in my opinion.


The error was not difficult to find but the intention of the author was something similar to this query:
"retrieve contacts where the account number of the parent account is X"

This kind of query was not possible to build with Dataverse REST Builder before, the filter capabilities were limited to the columns of the main table, so if you were retrieving contacts you were limited to contact columns.

With the new version of DRB (1.0.0.26) it's possible to add "Relationship Columns" from the N:1 relationships, the next screenshot shows how it appears:


I highlighted the new button available inside the UI, relationship columns have also a different background color (in order to separate them from primary table columns).
The first dropdown is connected to the available N:1 relationships, the second one will list the columns of the related table.
Two important things:
  1. Not all the operators are available when dealing with relationship columns, for example the "Today" operator for DateTime columns (because the syntax looks for properties inside the main table), so I removed this kind of operators for relationship columns.
  2. Not all the relationships can be navigated and filtered, like the "Owner" one (but you can use the "Owning Team" or the "Owning User"), they appear inside the UI but an error appear when the query is executed.
To my understanding both points are limitations of the platform but maybe I am wrong, hope it helps.

January 15, 2022

Dataverse Web API and REST Client VS Code extension

If you use Visual Studio Code and worked with API you probably know the extension called REST Client. It has more than 2 million downloads, the advantages are that you can use it inside Visual Studio Code (meaning you don't need to have or switch to Postman) and it has a file format (.http) to save the requests.

Let me be clear here, I prefer Postman but as I said many times not everybody uses the same tools so let's explore a bit how REST Client extension works.

If you don't consider authentication it's pretty simple, you write your endpoint and you can click to execute the request, something like this:

What if you need to deal with authentication and the query is against the Dataverse Web API endpoint?
REST Client supports different types of authentication, the one we will use to query the Dataverse endpoint is Client Credentials, recently my friend Benedikt Bergmann published a very useful post for Power Automate (link here) but you can use the first part to configure the App Registration and the required app user.
After we get the required details (Client Id, Client Secret and Tenant Id) we are ready to add the authentication to REST Client.
What I am writing here is not discovered by me, I just combined the information found from this Healthcare API Microsoft Docs page and this post by MVP Geert van der Cruijsen.

First of all we create/update the settings.json in order to add the required syntax by REST Client to add environment variables, like this:

{
    "rest-client.environmentVariables": {
        "$shared": {},
        "Dataverse": {
            "url": "https://mydemo.crm.dynamics.com",
            "tenantid": "89d6b4f0-f93c-4d88-800c-ff6acdae523a",
            "clientid": "71aa6fe0-040f-493f-b19d-9f248692bf93",
            "clientsecret": "notsosecret"
        }
    }
}

If you are familiar with REST Client you probably done something similar, in the above example we defined a "Dataverse" environment and we can use the defined variables.

REST Client format allows to save multiple requests in a single .http file and reuse variables filled by previous requests, the idea here is to first execute a request to get the bearer token and use it as authorization for the next requests.

If we use the V2 Endpoint the request would be like this:

### Get Access Token
# @name getAADToken
POST https://login.microsoftonline.com/{{tenantid}}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id={{clientid}}&client_secret={{clientsecret}}&scope={{url}}/.default

### Extract access token from getAADToken request
@token = {{getAADToken.response.body.access_token}}
  
We are using the variables defined inside the settings.json and store the bearer token inside a variable called token.

After we can add to the same .http file a request to Dataverse Web API using the token variable:
### Get Contacts
GET {{url}}/api/data/v9.1/contacts?$select=contactid,fullname
Authorization: Bearer {{token}}
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json; charset=utf-8
Accept: application/json
Prefer: odata.include-annotations=*
      
In this way you can now execute your queries inside REST Client.
Why I am writing this? because the latest version of Dataverse REST Builder I just published (1.0.0.24) has a new option to export the requests for REST Client.

The first option "Export REST Client Environment" allows you to create a sample settings.json with the variables I described above, the second option "Export as REST Client Collection (.http)" allows you to download the requests inside the collection as .http file including the authentication request (you can also select the V1 or V2 endpoint)

Hope it helps

January 12, 2022

Dataverse REST Builder and Lookups

When I created Dataverse REST Builder I liked very much the idea to use Xrm.Utility.lookupObjects, having a custom page using this function makes (at least for me) the application more integrated with the system, also many requests (like Retrieve Single or the Associate/Disassociate) require to insert the ID of a record.

When Dataverse REST Builder was executed inside XrmToolBox, the following message appeared:

To make up for this, inside the latest version (1.0.0.23) I added a lookup function when DRB is executed outside a Dynamics 365/Power Apps context, to facilitate users to search and select the ID of a record.
The functionality is simple and limited, after a table is selected a search term for the primary column must be specified (it works with a "contains"/"like" logic) and after click "Search" maximum 5 records are returned (ordered by the primary column of the table).
If one of the results is the one you wish, clicking the "Select" button will bring the ID and the table logical name back to the application.
Hope it helps.