Power Pages Web API

Kurzreferenz für CRUD-Operationen & Abfrageoptionen

Die Power Pages Web API verstehen

Die Power Pages Web API ermöglicht es client-seitigem JavaScript, CRUD-Operationen (Create, Read, Update, Delete) direkt im Browser gegen Dataverse-Tabellen durchzuführen. Im Gegensatz zu Liquid-Templates, die server-seitig gerendert werden, erlaubt die Web API dynamische Dateninteraktionen nach dem Laden der Seite — unverzichtbar für reaktionsfähige Power Pages-Anwendungen.

Die API folgt OData v4-Konventionen and supports powerful query options like $select, $filter, $expand, $orderby, and $top um genau die benötigten Daten abzurufen. Alle Anfragen müssen die Wrapper-Funktion webapi.safeAjax() verwenden, die das CSRF-Token-Management für Schreiboperationen automatisch übernimmt.

Sicherheitshinweis: Die Web API respektiert Table Permissions und Web-Rollen. Benutzer können nur auf Daten zugreifen, für die sie autorisiert sind. Jede Tabelle muss über Site-Einstellungen explizit für den Web-API-Zugriff aktiviert werden; bestimmte Felder können auf Whitelist oder Blacklist gesetzt werden.

📖 Leseoperationen

GET Einfaches Lesen
Alle Datensätze einer Tabelle mit webapi.safeAjax() abrufen
webapi.safeAjax({ type: "GET", url: "/_api/accounts", contentType: "application/json", success: function(data) { console.log("Records:", data.value); data.value.forEach(function(record) { console.log(record.name); }); } });
GET $select – Bestimmte Felder auswählen
Nur angegebene Eigenschaften zurückgeben, um die Leistung zu verbessern
/_api/accounts?$select=name,revenue
GET $filter – Ergebnisse filtern
Filterbedingungen mit OData-Operatoren anwenden (eq, ne, gt, lt, and, or)
/_api/accounts?$filter=revenue gt 90000
GET $orderby – Ergebnisse sortieren
Ergebnisse auf- oder absteigend sortieren
/_api/accounts?$orderby=revenue desc
GET $top – Datensätze begrenzen
Anzahl der zurückgegebenen Datensätze begrenzen
/_api/accounts?$top=10
GET $expand – Verknüpfte Datensätze einschließen
Verknüpfte Datensätze über Navigationseigenschaften abrufen
/_api/accounts?$expand=contact_customer
GET $count – Datensatzanzahl ermitteln
Gesamtanzahl der Datensätze zurückgeben
/_api/accounts?$count=true
GET Zeichenfunktionen
contains(), startswith(), endswith() für Textfilterung verwenden
/_api/accounts?$filter=contains(name,'Contoso')
GET Abfrageoptionen kombinieren
Mehrere Abfrageoptionen mit & verketten
/_api/accounts?$select=name&$filter=revenue gt 1000&$orderby=name&$top=5

✏️ Schreiboperationen

POST Datensatz erstellen
Neuen Datensatz mit JSON-Payload und webapi.safeAjax() erstellen
webapi.safeAjax({ type: "POST", url: "/_api/accounts", contentType: "application/json", data: JSON.stringify({ "name": "Sample Account", "revenue": 50000 }), success: function(data) { console.log("Record created:", data.accountid); } });
PATCH Datensatz aktualisieren
Vorhandenen Datensatz per ID mit webapi.safeAjax() aktualisieren
webapi.safeAjax({ type: "PATCH", url: "/_api/accounts(record-id)", contentType: "application/json", data: JSON.stringify({ "name": "Updated Name", "revenue": 100000 }), success: function(data) { console.log("Record updated"); } });
DELETE Datensatz löschen
Datensatz per ID mit webapi.safeAjax() löschen
webapi.safeAjax({ type: "DELETE", url: "/_api/accounts(record-id)", success: function() { console.log("Record deleted"); }, error: function(error) { console.error("Delete failed:", error); } });

🛠️ Helper Function

Generische Web-API-Funktion
Wiederverwendbare Funktion für beliebige Web-API-Operationen
function callWebAPI(method, entitySet, recordId, data, queryString) { var url = "/_api/" + entitySet; if (recordId) url += "(" + recordId + ")"; if (queryString) url += "?" + queryString; webapi.safeAjax({ type: method, url: url, contentType: "application/json", data: data ? JSON.stringify(data) : null, success: function(result) { console.log("Success:", result); return result; }, error: function(error) { console.error("Error:", error); } }); } // Usage Examples: callWebAPI("GET", "accounts", null, null, "$select=name&$top=5"); callWebAPI("POST", "accounts", null, {name: "New Account"}); callWebAPI("PATCH", "accounts", "record-id", {name: "Updated"}); callWebAPI("DELETE", "accounts", "record-id");

🔗 Dataverse Relationships

GET 1:N – Verknüpfte Datensätze lesen
1:N: $expand verwenden, um untergeordnete Datensätze abzurufen (z. B. Account → Contacts)
webapi.safeAjax({ type: "GET", url: "/_api/accounts(account-id)?$expand=contact_customer_accounts", success: function(data) { console.log("Child contacts:", data.contact_customer_accounts); } });
GET N:1 – Übergeordneten Datensatz lesen
N:1: $expand verwenden, um den übergeordneten Datensatz abzurufen (z. B. Contact → Account)
webapi.safeAjax({ type: "GET", url: "/_api/contacts(contact-id)?$expand=parentcustomerid_account", success: function(data) { console.log("Parent account:", data.parentcustomerid_account); } });
POST Erstellen mit N:1-Lookup
Untergeordneten Datensatz erstellen und über Lookup-Feldbindung mit übergeordnetem verknüpfen
webapi.safeAjax({ type: "POST", url: "/_api/contacts", contentType: "application/json", data: JSON.stringify({ "firstname": "John", "lastname": "Doe", "parentcustomerid_account@odata.bind": "/accounts(account-id)" }) });
PATCH N:1-Beziehung aktualisieren (Methode 1)
Lookup per @odata.bind-Annotation in PATCH-Anfrage aktualisieren
webapi.safeAjax({ type: "PATCH", url: "/_api/contacts(contact-id)", contentType: "application/json", data: JSON.stringify({ "parentcustomerid_account@odata.bind": "/accounts(new-account-id)" }) });
PUT N:1-Beziehung aktualisieren (Methode 2)
Referenz per PUT auf den $ref-Endpunkt mit @odata.id ändern
webapi.safeAjax({ type: "PUT", url: "/_api/contacts(contact-id)/parentcustomerid_account/$ref", contentType: "application/json", data: JSON.stringify({ "@odata.id": "/_api/accounts(new-account-id)" }) });
DELETE N:1-Lookup entfernen (Trennen)
Einfache Navigationseigenschaft per DELETE auf dem $ref-Endpunkt entfernen
webapi.safeAjax({ type: "DELETE", url: "/_api/contacts(contact-id)/parentcustomerid_account/$ref", success: function() { console.log("Lookup cleared"); } });
GET N:N – Many-to-Many lesen
N:N: $expand mit Beziehungskollektion verwenden (z. B. Contact → Marketing-Listen)
webapi.safeAjax({ type: "GET", url: "/_api/contacts(contact-id)?$expand=listmember_association", success: function(data) { console.log("Marketing lists:", data.listmember_association); } });
POST N:N – Datensätze verknüpfen
Many-to-Many-Beziehung über den $ref-Endpunkt erstellen
webapi.safeAjax({ type: "POST", url: "/_api/contacts(contact-id)/listmember_association/$ref", contentType: "application/json", data: JSON.stringify({ "@odata.id": "/_api/lists(list-id)" }) });
DELETE N:N – Datensätze trennen
Many-to-Many-Beziehung per $ref mit $id-Abfrageparameter entfernen
webapi.safeAjax({ type: "DELETE", url: "/_api/contacts(contact-id)/listmember_association/$ref?$id=/_api/lists(list-id)", success: function() { console.log("Relationship removed"); } });
Namen der Navigationseigenschaften
Beziehungsnamen im Power Pages Design Studio oder über den $metadata-Endpunkt ermitteln
/_api/$metadata // Look for NavigationProperty elements // Example: contact_customer_accounts

🔐 Sicherheit & Configuration

Table Permissions erforderlich
Web API respektiert Table Permissions. Konfiguration über Portal Management → Table Permissions + Web Roles
Benutzer können nur auf Daten zugreifen, die ihre Web-Rolle autorisiert
Web API pro Tabelle aktivieren
Muss in den Site-Einstellungen für jede Tabelle aktiviert werden
Webapi/<tablename>/enabled = true
Webapi/<tablename>/fields = name,email,phone
CSRF-Token erforderlich
Schreiboperationen erfordern ein CSRF-Token. webapi.safeAjax() verwenden
webapi.safeAjax({
type: "POST",
url: "/_api/accounts",
data: JSON.stringify({name: "Test"})
})

Kurzreferenz-Übersicht

Leseoperationen (GET)

  • $select – Nur bestimmte Felder zurückgeben
  • $filter – Bedingungen anwenden (eq, gt, contains)
  • $expand – Verknüpfte Datensätze einschließen
  • $orderby – Ergebnisse sortieren (asc/desc)
  • $top – Datensatzanzahl begrenzen

Schreiboperationen

  • POST – Neue Datensätze erstellen
  • PATCH – Vorhandene Datensätze aktualisieren
  • DELETE – Datensätze löschen
  • PUT /$ref – Beziehungen aktualisieren

Beziehungsmuster

  • 1:N – $expand auf Parent für untergeordnete Datensätze
  • N:1 – @odata.bind für Lookup-Zuweisung
  • N:N – POST/DELETE an /$ref-Endpunkt

Sicherheitsgrundlagen

  • Immer webapi.safeAjax() verwenden
  • Table Permissions konfigurieren
  • Tabellen über Site Settings aktivieren
  • Felder explizit auf Whitelist setzen

Profi-Tipp: Abfrageoptionen für optimale Leistung kombinieren: /_api/accounts?$select=name,revenue&$filter=revenue gt 10000&$orderby=name&$top=50