Oct 18, 2023

Write a Custom API and call from Workflow

A Custom API is comparatively a new mechanism to create your own API in Dataverse. This is like a Action where you can package few steps to accomplish something. Advantage is you can then call from anywhere, either client side or server side etc. Obviously it can be called via a workflow or Cloud Flow too. Custom API is more flexible since coding is possible.

In this scenario we will see how to create a simple Custom API and call it from a classic workflow.

Writing a Custom API

1) We need to write a code which is pretty similar to a Plug-in. This is where we define our logic. In my case I am accepting a parameter string (i.e. DetailStr) and update Description (i.e. so_description) field of the custom entity called Office (i.e. so_office).

namespace AccAdmin.Plugins.CustomApi
{
    public class UpdateOffice : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context;
            IOrganizationServiceFactory factory;
            IOrganizationService service;

            try
            {
                context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

                if (!context.InputParameters.Contains("DetailStr"))
                    throw new InvalidPluginExecutionException($"DetailStr not designated or Invalid..");

                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference target)
                {
                    if (target.LogicalName != "so_office") return;
                    factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    service = factory.CreateOrganizationService(context.UserId);

                    Entity entity = new Entity();
                    entity.LogicalName = "so_office";
                    entity.Id = context.PrimaryEntityId;
                    entity["so_description"] = (string)context.InputParameters["DetailStr"];
                    service.Update(entity);
                }
            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                throw e;
            }
            finally
            {
                service = null;
                factory = null;
                context = null;
            }
        }
    }
}

2) Once register the Plug-in, Custom API step will be visible as a step as below.


3) Now we start configuration. First add new Custom API to your solution.
    

Once save my Custom API was seen like below. It will have an unique name which we use to call this. We have set Enable for Workflow = Yes since we plan to call this from a Workflow. Most importantly, we have set our Plug-in step as the Plugin Type which is the linking point of our logic to the API. 


* Idea of all other settings

4) Same way we added the Custom API, we now add a parameter to our solution. Parameter is optional. In our case we plan to pass a string parameter.


Once created, parameter was seen as below. Nothing complex about this. You may notice we have selected Custom API we defined in previous step is set here for Custom API field.


Now we are done with our Custom API

Calling the Custom API from Workflow

Here I am create just an On Demand workflow so we can easily check it.

5) I am initiating a very simple Async workflow against Office entity.


6) Now I am adding a step of performing an Action. Interestingly, when I check the list of available Actions, I am seeing my Custom API by its unique name.


I see two parameters here. One is Target where we need to pass the current office record. Other one is what we define in Custom API which is needed for our logic.


7) Now its a matter of running our Workflow On Demand for any selected Office record.

* 
Unique Name: Unique name for the Custom API (Start with the publisher’s prefix which you have specified on your solution).

Name: Name for the Custom API.

Display Name: Display Name for this Custom API. In case we have enabled multi-languages on the System, we can provide a specific name for the custom API based on the language.

Description: This field is to store the description of this Custom API.

Binding Type: The Binding Type is the Options set field and could be set as Global, Entity, and Entity Collection. This should be specified as per your operation requirement (Entity Collection is only supported in Function Type Custom API).

Bound Entity Logical Name: This field is required when we select the Binding Type as Entity or Entity Collection. For the binding type as Global, it can be empty.

Is Function: It defines whether your custom API is a Function (this can only be called using Get Method) or Action (this can only be called using POST method).

Is Private: To define the Custom API is private or public (setting it private makes it accessible to only the owner of the Custom API).

Allowed Custom Processing Step Type: Allowed Custom Processing Step Type is another Option set field with options like None, Async Only, Sync, and Async. These options let you define whether the other plugins could be registered on this Custom Message and also lets you define its behavior. Like Async Only allows the plugins to register only onPost operation with Execution Mode to Asynchronous, and same for the Sync and Async option.

Execute Privilege Name: We can define the privilege that allows execution of the custom API. As per Microsoft docs, we can also create custom privileges and it is currently in development. We can use OOB privileges, for example,prvCreateLead, prvWriteLead, etc.

Plugin Type: Set the reference of your plugin for this API.

Warning
This example works fine. Anyway, there has been some deployment issues reported as per now we write this. So it is always advisable to call your Custom API from a Cloud Flow than a classic workflow. That worked perfectly.

No comments:

Post a Comment