Cosa sono le Custom API

Una Custom API è il meccanismo moderno e code-first per definire un messaggio custom in Microsoft Dataverse, esattamente come lo sono i messaggi standard Create, Update o WinOpportunity. Invece di limitarti a estendere un messaggio esistente con un plug-in, tu ne pubblichi uno nuovo, con un nome univoco (es. contoso_RecalculatePricing), i suoi parametri di input e output, e la logica di business associata.

Una Custom API si compone di più tabelle di sistema, tutte solution-aware (esportabili in una solution gestita):

  • Custom API: definisce il messaggio (unique name, binding type, plug-in della main operation, comportamento di sicurezza).
  • Custom API Request Parameter: i parametri di input tipizzati (String, Integer, Boolean, EntityReference, Entity, EntityCollection, Guid, ecc.), ciascuno marcabile come Is Optional.
  • Custom API Response Property: i valori restituiti nella response, anch’essi tipizzati.

Binding: bound vs unbound

Il Binding Type determina come il messaggio viene invocato:

  • Global (unbound): non legato ad alcuna tabella. È la scelta per logica trasversale (es. un motore di calcolo).
  • Entity (bound): opera su un singolo record; l’invocazione richiede il riferimento alla riga specifica.
  • Entity Collection (bound): legato a una tabella ma non a un record specifico.

Il binding influenza la sintassi dell’URL Web API e determina se il primo parametro (Target) è implicito.

Plug-in della main operation

La logica principale risiede in un plug-in type registrato sullo stage Main Operation (stage 30) del nuovo messaggio. È qui la differenza sostanziale rispetto al passato: la Custom API dà a uno sviluppatore pieno controllo sul codice C#, con debugging, unit test e gestione delle eccezioni. Il campo Is Function distingue una function (semantica GET, sola lettura, deve restituire almeno una response property) da un’action (semantica POST, può avere side effect).

Custom API vs Custom Action (workflow-based)

Le classiche custom process action si creano nel designer dei workflow (processo di tipo Action) e possono contenere step no-code oppure invocare assembly. La Custom API le supera per gli scenari pro-code:

  • Solo Custom API offre Is Private e il controllo sui processing step aggiuntivi.
  • La Custom API è code-first e più performante: nessun overhead del motore workflow.
  • Le custom action restano utili quando si vuole comporre logica no-code/low-code riutilizzabile, o quando serve un’action richiamabile da Power Automate/flow senza scrivere codice.

Regola pratica: se la logica è in C# e vuoi un contratto pulito e riusabile, usa una Custom API; se stai già lavorando con un message standard e devi solo agganciare comportamento a un evento (es. validazione al Create), registra un plug-in su quel message standard, non creare un messaggio nuovo.

Proprietà da non sbagliare

  • Is Private: nasconde la Custom API dai metadati pubblici e dalla documentazione. Segnala che è per uso interno alla solution; non è una barriera di sicurezza vera e propria, ma scoraggia l’uso esterno e ne consente future modifiche.
  • Allowed Custom Processing Step Type (spesso “Enabled for Workflow”/step aggiuntivi): controlla se altri plug-in possono registrare step sul tuo messaggio. Valori: None (nessuno step esterno), Async Only, Sync and Async. Impostalo a None per proteggere un contratto sensibile.
  • Execute Privilege Name: privilegio opzionale che gate l’esecuzione, per restringere chi può chiamare l’API.

Come invocare una Custom API

Da Web API (action unbound, POST):

POST [Organization URI]/api/data/v9.2/contoso_RecalculatePricing
{ "Amount": 100 }

Le function unbound si chiamano in GET con i parametri tra parentesi.

Da codice server / plug-in con IOrganizationService:

var req = new OrganizationRequest("contoso_RecalculatePricing");
req["Amount"] = 100m;
var resp = service.Execute(req);

Da client-side (model-driven app) con Xrm.WebApi.online.execute, fornendo l’oggetto request e il relativo getMetadata() che descrive boundParameter, operationType (0=action, 1=function) e parameterTypes.

Trappole tipiche d’esame

  • Scenario: logica C# riusabile richiamabile da JavaScript e da altri plug-in, con contratto tipizzato → crea una Custom API con plug-in sulla main operation (non una custom action workflow, non solo un plug-in su message standard).
  • Scenario: devi validare/arricchire un record durante il suo Create/Updateregistra un plug-in sul message standard (pre/post-operation), non definire una Custom API.
  • Scenario: nessun altro sviluppatore deve poter agganciare step al tuo messaggio → imposta Allowed Custom Processing Step Type = None.
  • Scenario: la Custom API è di sola lettura e non modifica dati → marcala come Is Function (semantica GET) e definisci almeno una response property.
  • Scenario: vuoi che l’API resti modificabile e non documentata per il pubblico → attiva Is Private (ricordando che non sostituisce controlli di sicurezza come Execute Privilege Name).