Dataverse Custom API Toolkit: Custom-API-Endpunkte direkt in VS Code bauen
Dataverse Custom API Toolkit: Custom-API-Endpunkte direkt in VS Code bauen
Wenn du in Dataverse schon mal eine Custom API von Hand angelegt hast, kennst du das Gefummel: Im Maker Portal klickst du dich durch Message, Request-Parameter und Response-Properties, tippst uniqueName, bindingType und Typen einzeln ein — und merkst erst beim ersten Aufruf, dass ein Parameter fehlt, ein Name einen Buchstabendreher hat oder eine Response-Property nie angelegt wurde. Kein Diff, keine Versionierung, kein „vorher mal trocken durchspielen”.
Das Dataverse Custom API Toolkit ist eine VS-Code-Extension, die genau diese Arbeit in den Editor holt. Sie ist ein grafischer Aufsatz auf die CLI dataverse-custom-api (dvc): Du siehst deine Custom-API-Endpunkte in einem Tree, bearbeitest ihre Parameter in einem Formular, exportierst sie als versionierbare JSON-Datei in deinen Workspace und spielst Änderungen erst als Simulation, dann live gegen Dataverse. Kernregel wie beim manuellen Weg vermieden: du siehst vor jedem Schreibvorgang genau, was passieren würde.
Grundbegriffe: Custom API, Request-Parameter, Response-Property
Kurz eingeordnet, falls du nicht täglich damit arbeitest:
- Eine Custom API ist eine benutzerdefinierte Nachricht (Action oder Function) in Dataverse — also ein eigener Endpunkt, den du wie
WhoAmIoderCreateaufrufen kannst, nur mit deiner eigenen Logik dahinter. Definiert wird sie über Metadaten: Name, Binding, ein optionaler Plugin-Typ, plus ihre Parameter. - Ein Request-Parameter ist ein Eingabewert der API — mit
uniqueName, Typ (String, Integer, Entity …) und dem Flag, ob er optional ist. - Eine Response-Property ist ein Rückgabewert — Name und Typ, den der Aufrufer zurückbekommt.
Statt dieses Geflecht im Portal zu klicken, beschreibst du es als JSON und lässt das Toolkit den Abgleich mit Dataverse machen.
Screen für Screen: die Oberfläche
Nach der Installation bekommst du in der Activity Bar ein eigenes Icon des Dataverse Custom API Toolkit. Dahinter sitzen drei Panels: Environments, Custom API und Actions.

1. Environments — deine Umgebungen
Die Environments-View listet deine gespeicherten Dataverse-Umgebungen. Umgebungen werden global in der Extension verwaltet (nicht pro Workspace), Secrets liegen sicher in VS Codes context.secrets — nie im Klartext im Projekt.
In der Titelleiste der View sitzen Connect Environment (+) und Refresh. Pro Eintrag hast du inline Use (verbinden/aktiv setzen), Edit und Remove.
Connect Environment öffnet einen geführten Assistenten — eine Kette von Eingabefeldern oben im VS-Code-Fenster:
- Display Name — ein sprechender Name.
- Dataverse Environment URL — z. B.
https://org.crm4.dynamics.com(wird aufhttp…geprüft). - Authentication Mode — Auswahl aus deviceCode (Device Code Flow, empfohlen), interactiveBrowser (Browser-Login) oder clientSecret (App-only).
- Tenant ID und Client ID deiner Azure-AD-App-Registrierung.
- Client Secret — nur bei
clientSecret, als verdecktes Passwortfeld; landet in den VS-Code-Secrets.
Zum Schluss schreibt die Extension eine kompatible auth.json in ihren Runtime-Cache (die Brücke zur CLI) und ruft connect auf.

2. Custom-API-Ansicht — dein Arbeitsbereich
Das Herzstück. Die Custom-API-View listet jede Custom API der aktiven Umgebung. Jeder Eintrag zeigt neben dem uniqueName einen Status als Kurztext: local · dirty · active — und ein passendes Icon:
- grüner Haken — aktive API, lokal und in sync,
- ⚠ Warnung — lokale Datei weicht von der zuletzt gespeicherten ab (dirty),
- Code-Datei-Icon — lokal exportiert, sauber.
Oben rechts zeigt ein Badge die Anzahl (z. B. „7 von 20”, wenn ein Filter aktiv ist). In der Titelleiste sitzen Refresh, Filter und Search by Name; der Titel spiegelt aktive Filter als Chips wider — etwa Custom API · no private · Global, Entity · "reorder".
Pro Eintrag hast du inline: Use (als aktive API setzen), Export (aus Dataverse in eine lokale JSON ziehen) und — sobald eine lokale Datei existiert — Open JSON, Edit und Save & Sync. Im Kontextmenü zusätzlich Diff vs Remote und Remove Local.

3. Der Custom-API-Editor — das eigentliche Bearbeiten
Klickst du bei einer lokalen API auf Edit, öffnet sich ein Formular-Editor (Webview) als eigener Tab „Edit <uniqueName>”. Der Titel bekommt einen ● Punkt, sobald du etwas Ungespeichertes hast, und ganz oben erscheint ein Dirty-Banner („Unsaved changes — Save to write locally, or Reset to discard.”).
Der Editor hat drei Abschnitte:
General — die Kopfdaten der API in einem Raster: Unique Name (mit immutable-Badge und der Warnung, dass eine Änderung die ganze API löschen und neu anlegen würde), Display Name, Name, Binding Type (Global / Entity / EntityCollection), Description, Execute Privilege Name, Bound Entity Logical Name, die Plugin-Felder (Plugin Type Name, Plugin Type ID schreibgeschützt, Plugin Assembly Name …) und Allowed Custom Processing Step Type (None / AsyncOnly / SyncAndAsync). Dazu drei Checkboxen: Is Function, Is Private, Workflow SDK Step Enabled.
Request Parameters — eine Tabelle (Unique Name · Display Name · Description · Type · Optional · Actions) mit Add Parameter. Jede Zeile lässt sich aufklappen, um Details wie Logical Entity Name zu setzen.
Response Properties — dieselbe Idee ohne die Optional-Spalte, mit Add Property.
Für Type hast du überall dieselbe feste Auswahl: Boolean, DateTime, Decimal, Entity, EntityCollection, EntityReference, Float, Integer, Money, Picklist, String, StringArray, Guid.
Unten die Werkzeugleiste: Save, Save & Sync to Dataverse, Reset, Preview Payload, Open Saved JSON und — falls die CLI es unterstützt — Diff with Remote.
Der Custom-API-Editor mit aufgeklapptem Request-Parameter ccsm_TargetItem — Type, Logical Entity Name und Unique Name tragen das immutable-Badge. Oben zeigt das gelbe Dirty-Banner ungespeicherte Änderungen; das geänderte Feld bekommt einen gelben Rand.
Die helle Variante — unten die vollständige Werkzeugleiste: Save, Save & Sync to Dataverse, Reset, Preview Payload, Open Saved JSON, Diff with Remote.
4. Der Sync-Plan — erst schauen, dann schreiben
Save schreibt nur die lokale JSON. Save & Sync to Dataverse öffnet daneben den Sync-Plan (Webview „Sync: <uniqueName>”). Zuerst läuft eine Fortschritts-Notification („Checking sync status…”): Das Toolkit diffed deine lokale Definition gegen Dataverse. Ist alles gleich, meldet es schlicht „already in sync — no changes needed” und macht nichts.
Gibt es Unterschiede, siehst du eine Operationsliste — jede geplante Änderung als eigene Zeile. Wenn destruktive Schritte nötig sind (weil ein immutables Feld geändert wurde), erklärt ein Abschnitt „⚠ Why are destructive operations needed?” im Klartext, welches Feld sich geändert hat und warum daraus ein Löschen-und-Neu-Anlegen folgt.
Zwei Buttons: Simulate (Dry Run — spielt jede Operation durch, ohne zu schreiben) und Execute (live). Jede Operation bekommt live einen Status: running → ok / failed samt Dauer; bei einem Fehler stoppt der Lauf.
Der Sync-Plan vor dem Schreiben: ein recreate ist nötig, weil sich der Typ von ccsm_NewPosition geändert hat — der gelbe Kasten erklärt genau warum. Nichts wird geschrieben, bis du auf Execute klickst.
Dieselbe Ansicht hell — die Aktions-Badges (update, create, recreate) und der ⚠ destructive-Marker bleiben in beiden Themes farblich eindeutig.
5. Actions & Diff
Die Actions-View ist dein Statusboard: Sie zeigt oben die aktive Umgebung (mit URL) und die aktive Custom API, darunter Schnellzugriffe: Connect Environment, Refresh, Export Current API, Diff Current API, Save & Sync to Dataverse.
Diff öffnet den Metadaten-Vergleich lokal ↔ Dataverse als JSON-Dokument daneben — praktisch, um vor dem Sync genau zu sehen, was abweicht.

Der Workflow in einem Satz
Umgebung verbinden → Custom API auswählen → Export (Dataverse → lokale JSON) → im Formular editieren → Preview Payload / Diff prüfen → Simulate (Dry Run) → Execute (live).
Weil die exportierte JSON in deinem Workspace liegt, kannst du sie ganz normal versionieren (Git), im Team reviewen und über den Diff jederzeit gegen die Umgebung abgleichen. Änderst du die Datei direkt im Text-Editor oder per CLI, merkt die Extension das über einen File-Watcher und aktualisiert den Tree.
Validierung & Diagnostics
Das Toolkit fängt Fehler an mehreren Stellen ab, bevor sie in Dataverse einschlagen.
Direkt im Editor markiert es immutable Felder mit einem Badge und warnt, wenn du eines änderst — denn Dataverse lässt manche Felder nicht nachträglich ändern, sondern nur per delete + recreate. Änderst du z. B. den Typ eines Request-Parameters, plant das Toolkit automatisch ein Ersetzen statt eines Updates und sagt dir das im Sync-Plan.
Als eigene Aktion gibt es zusätzlich Check Metadata Consistency: Ein Klick prüft, ob deine lokale Definition noch deckungsgleich mit Dataverse ist. Ist alles sauber, siehst du „No metadata mismatches found” — inklusive der vollständigen Request-Parameter- und Response-Property-Listen.

Die tiefere Regelprüfung liefert die CLI (dvc api validate) — rein lokal, blockiert nichts, gibt dir sofort Feedback. Diese Regeln solltest du im Kopf haben:
| Regel | Bedeutung |
|---|---|
uniqueName mit Publisher-Präfix (z. B. ccsm_), max. 128 Zeichen | Ohne Präfix / zu lang → Fehler |
name / displayName max. 100 Zeichen | Überschreitung → Fehler |
description max. 300 Zeichen | Überschreitung → Fehler |
bindingType ∈ Global / Entity / EntityCollection | Anderer Wert → Fehler |
boundEntityLogicalName bei Entity / EntityCollection | Pflicht, sonst Fehler |
logicalEntityName nur bei Typ Entity / EntityReference | Sonst überflüssig / Info |
| Function braucht ≥ 1 Response-Property | Sonst Fehler |
Die Severity-Stufen der CLI:
| Severity | Heißt |
|---|---|
| error | Blockierend — Dataverse würde die Anlage mit einem 400 ablehnen. |
| warning | Wird akzeptiert, weicht aber von der Empfehlung ab. |
| info | Hinweis, z. B. ein offener Entity-Typ ohne logicalEntityName. |
Jeder Befund kommt als strukturierter JSON-Envelope (CcdvCommandResult) mit code, jsonPath und suggestedFix — genau das Format, das sich später sauber ins VS-Code-Problems-Panel bzw. als Quick Fix einklinken lässt.
Berechtigungen: der häufige Stolperstein
Damit ein Sync durchläuft, braucht der verbundene Benutzer die passenden Rechte. Die CLI prüft das mit dvc api validate-privileges: prvRead/Create/Write/Delete auf CustomAPI, dazu prvAppendToPluginType und prvCreateSdkMessageProcessingStep.
Dieselbe Prüfung gibt es als Ein-Klick-Aktion in der Extension — Validate App-User Privileges in der Actions-Leiste. Das Ergebnis erscheint im Output-Kanal „DVC”: jedes der sechs Rechte mit grünem Haken und die Klartext-Zusammenfassung „All 6 privileges available”.

Wichtig ist der Graceful Fallback: Fehlt prvAppendToPluginType, bricht der Lauf nicht hart ab — das Toolkit legt die Custom API stattdessen ohne Plugin-Typ-Bindung an und gibt eine Warning aus. Du bekommst also ein nutzbares Ergebnis plus den klaren Hinweis, welches Recht fehlt. Im Extension-UI äußert sich ein echtes Rechteproblem als fehlgeschlagene Operation im Sync-Plan (Status failed mit Meldung).
Unter der Haube
Die Extension baut die Dataverse-Aufrufe nicht selbst — sie ist ein Wrapper um das npm-Paket ccdvcustomapi (dieselbe Engine wie die dvc-CLI). Über eine kompatible auth.json im Runtime-Cache reicht sie deine Umgebungs- und Auth-Daten an die CLI-Engine weiter; Secrets bleiben derweil in den VS-Code-Secrets. Custom-API-Definitionen liegen als JSON-Katalog im Workspace, jede Änderung geht über denselben Envelope (CcdvCommandResult) wie in der CLI.
Zwei Details, die den Alltag angenehm machen:
- Dirty-Erkennung per Hash. Beim Export merkt sich das Toolkit einen Hash der Datei. Änderst du sie später, vergleicht es neu und markiert die API im Tree als dirty — du siehst also auf einen Blick, was noch nicht synchronisiert ist.
- File-Watcher. Legst du eine Custom-API-JSON per CLI an oder editierst sie im Text-Editor, aktualisiert sich der Tree automatisch. Extension und CLI teilen sich denselben Workspace-Ordner, ohne sich in die Quere zu kommen.
Installieren & loslegen
Voraussetzung ist die CLI dataverse-custom-api (@brunsforge/dataverse-custom-api) — die Extension ist der grafische Aufsatz darauf. Den Quellcode und die Dokumentation der CLI findest du offen auf GitHub: github.com/brunsforge/dataverse-custom-api.
Die Extension liegt im Visual Studio Marketplace als Dataverse Custom API Toolkit (Publisher brunsforge). Installieren direkt in VS Code über Extensions → „Dataverse Custom API Toolkit” oder per Kommandozeile:
code --install-extension brunsforge.dataverse-custom-api-toolkit
Der Kurz-Workflow, wenn alles installiert ist: In der Activity-Bar-Ansicht des Toolkits über Connect Environment deine Dataverse-Umgebung verbinden (Device Code reicht), in der Custom-API-Ansicht die gewünschte API mit Export lokal ziehen, mit Edit im Formular anpassen, mit Preview Payload oder Diff prüfen, was sich ändern würde, dann Save & Sync öffnen und den Plan erst Simulate, dann Execute. Ab da lebt deine Custom-API-Definition als versionierte JSON in deinem Repo — reviewbar, diffbar, wiederholbar.