-
Notifications
You must be signed in to change notification settings - Fork 2
Custom APIs
Define a Custom API as a file in your repo, generate the C# handler and a typed TypeScript client from it, and deploy it to your environment — so the API's shape lives in source control next to the plug-in that implements it, rather than only in the environment you last clicked it into.
Preview feature. Tick Preview features in the panel footer to see these commands.
A Custom API is a *.customapi.json file directly inside a Plugins component, because a Custom
API is implemented by a plug-in type. One file per API. The commands are on the plugin card's overflow
(…) menu:
| Command | What it does |
|---|---|
| New Custom API definition | Scaffolds <UniqueName>.customapi.json with a sample request parameter and response property |
| Generate Custom API handlers | Writes/refreshes the C# handler class for each definition |
| Generate Custom API TS clients | Writes a typed TypeScript client for each definition |
| Deploy Custom APIs | Creates or updates the API, its request parameters and its response properties in the environment |
| Run Custom API… | Calls a deployed API and shows the response |
New Custom API definition asks for two things:
- the unique name (e.g.
dvpt_CalculateRebate) — the name callers use; - the plug-in type name, defaulted from that unique name (e.g.
Dataverse.Plugins.CalculateRebate) — the class that will implement it.
The result is a JSON file describing the API: its binding, whether it is a function or an action, its request parameters and its response properties. Edit that file as the source of truth — everything below is generated from it, and validation errors are reported per file with the offending field named, so a typo is caught before it reaches the environment.
Generate Custom API handlers writes the C# side into your plug-in project, at
<PluginProject>/CustomApi/<Class>.generated.cs: typed request and response wrappers plus an IPlugin
class with a TODO. Fill that in — read the inputs from request, set the outputs on response:
response.OutputValue = "echo: " + request.InputValue;Generate Custom API TS clients writes the TypeScript side to clients/<Class>.client.ts — a typed
function a web resource or PCF control can call. Copy it into that project.
Re-run either after editing the definition.
Regenerating overwrites the whole file, including the logic you wrote in
Execute. Until that changes (#254), either keep your implementation somewhere else and call it fromExecute— a one-line call is safe to retype — or copy the file before regenerating.
Deploy Custom APIs validates every definition in the component, then for each one:
- creates the Custom API if it is absent, or updates it if it exists (matched on unique name);
- reconciles the request parameters and response properties — creating what is new, updating what changed, and deleting what you removed from the definition, so the environment ends up matching the file rather than accumulating members from earlier versions;
- adds it to your solution.
Deploy the implementing plug-in as well (Build & deploy package on the same card) — the Custom API row points at a plug-in type, so the type has to exist.
Run Custom API… picks a definition, prompts for each request parameter, calls the API and shows what came back.
Global (unbound) APIs only. A Custom API bound to a table or an entity collection cannot be invoked from here yet — the command says so and points you at the generated TypeScript client, which handles bound calls.
The full loop — define, generate, deploy the package, deploy the API, call it — runs against a live
environment in the automated end-to-end suite, which checks the customapi row and its members in
Dataverse and asserts the response the handler returns. Sign-off for un-gating the feature is tracked in
#225.
The commands are not in the menu — tick Preview features in the panel footer, and make sure the active component is a Plugins component.
"✗ <name>: N validation error(s)" — the definition failed validation and was skipped; each error names its field. Nothing is deployed for that file until it is clean.
"Running bound Custom APIs isn't supported yet" — expected, see above; use the generated TS client.