Wenn Frontend und PHP-Backend getrennt entwickelt oder bereitgestellt werden, kann jedes Team Änderungen in seinem eigenen Tempo veröffentlichen. Diese Autonomie erleichtert die Arbeitsorganisation, schafft aber auch einen Reibungspunkt: Eine Benutzeroberfläche erwartet möglicherweise ein Feld, ein Format oder einen Status, den die API nicht mehr liefert. Das Problem lässt sich nicht dadurch lösen, dass beide Teams immer gleichzeitig Änderungen vornehmen. Die Lösung sind ein expliziter Vertrag, klar abgegrenzte Verantwortlichkeiten und Tests, die prüfen, wie die Integration tatsächlich genutzt wird.
Ein Vertrag zwischen Frontend und PHP-Backend beschreibt die Daten und Verhaltensweisen, die eine Seite anbietet und die andere konsumiert. Er ist nicht nur eine Liste von Routen, sondern umfasst Methoden, Parameter, Antwortschemata, Fehler, Berechtigungen und Kompatibilitätsregeln. Ziel ist, dass sich beide Seiten weiterentwickeln können, ohne von den internen Details der jeweils anderen abhängig zu sein.
Warum unabhängige Versionen Reibung erzeugen

Benutzeroberfläche und Server können unterschiedliche Release-Zyklen haben, und möglicherweise erhalten nicht alle Benutzer die neue Version gleichzeitig. Ein im Cache gespeichertes Frontend kann weiterhin eine alte Anfrage senden, nachdem das Backend aktualisiert wurde. Auch der umgekehrte Fall ist möglich: Die API führt eine Funktion ein, die der Benutzeroberfläche noch nicht bekannt ist.
Inkompatibilitäten treten oft bei scheinbar kleinen Änderungen auf: eine Eigenschaft umbenennen, eine Zahl in Text umwandeln, ein optionales Feld verpflichtend machen, das Format eines Datums ändern oder einen Fehler in einer anderen Struktur zurückgeben. Eine Änderung kann für den Servercode gültig sein und trotzdem bestehende Verbraucher beeinträchtigen.
Es ist sinnvoll, die Implementierung vom Vertrag zu unterscheiden. Das Backend kann seine Datenbank ändern oder interne Dienste neu organisieren, ohne die API zu beeinträchtigen, solange es das veröffentlichte Verhalten beibehält. Ebenso kann das Frontend seine Komponenten neu gestalten, ohne dass dafür die Geschäftsregeln geändert werden müssen.
Was zur Benutzeroberfläche, zur API und zur Domäne gehört
Die Benutzeroberfläche kümmert sich um die Nutzungserfahrung: Sie stellt Informationen dar, führt Benutzer durch Abläufe, gibt unmittelbare Rückmeldung zu Formatfehlern und steuert visuelle Zustände wie Laden, Erfolg oder keine Ergebnisse. Diese Prüfungen verbessern die Interaktion, sind aber keine Sicherheitsbarriere: Anfragen können geändert oder ohne die offizielle Benutzeroberfläche gesendet werden.
Die API vermittelt zwischen dem externen Protokoll und der Anwendung. Sie validiert die Form der Anfrage, authentifiziert oder autorisiert bei Bedarf, wandelt Daten um und kommuniziert vorhersehbare Antworten. Sie muss eine stabile Darstellung beibehalten, auch wenn sich interne Klassen oder das Persistenzschema ändern.
Die Domäne enthält die Regeln, die bestimmen, welche Vorgänge für das Geschäft gültig sind: beispielsweise, ob ein Statusübergang zulässig ist oder ob ein Vorgang eine Vorbedingung erfordert. Diese Regeln dürfen nicht ausschließlich in JavaScript existieren oder unabhängig in verschiedenen Controllern wiederholt werden. Das Backend muss sie durchsetzen, denn es ist die maßgebliche Instanz, die den Vorgang annimmt oder ablehnt.
Eine Regel kann vorläufig im Frontend geprüft werden, um den Benutzer anzuleiten; die endgültige Entscheidung wird jedoch erneut auf dem Server überprüft. Die visuelle Prüfung ersetzt weder die Validierung noch die Autorisierung im Backend.
Eingaben, Ausgaben, Fehler und Zustände festlegen
Dokumentiert für jeden Vorgang mindestens Methode und Route, Parameter, erforderliche und optionale Felder, Typen, Formate, relevante Einschränkungen und die Form der Antwort. Klärt auch, was es bedeutet, wenn ein Feld fehlt, null ist oder eine leere Liste enthält: Diese Zustände sind nicht immer austauschbar.
Die Antwort sollte dem Verbraucher ein verständliches Ergebnis vermitteln und keine Implementierungsdetails preisgeben. Legt HTTP-Statuscodes und eine einheitliche Fehlerstruktur fest, die einen stabilen Code oder eine Kategorie, eine für die Benutzeroberfläche geeignete Meldung und gegebenenfalls feldbezogene Fehler umfasst. Gebt keine Stacktraces, SQL-Abfragen oder vertraulichen Informationen preis. Das Frontend kann bekannte Codes in lokalisierte Meldungen übersetzen, statt von internen Texten abzuhängen, die sich ändern könnten.
Beschreibt auch Zustände, die den Ablauf beeinflussen: nicht vorhandene Ressource, verweigerter Zugriff, Konflikt mit dem aktuellen Zustand, fehlgeschlagene Validierung oder Ratenbegrenzung, sofern zutreffend. Legt bei paginierten Daten fest, wie Ergebnisse, Grenzen und Fortsetzungen dargestellt werden. Gebt bei Datumsangaben Format und Zeitzone sowie bei Beträgen Währung und Einheit an. Je weniger jedes Team auf Schlussfolgerungen angewiesen ist, desto geringer ist die Gefahr von Abweichungen.
In beiden Schichten validieren, ohne die Domäne zu duplizieren
Manche Validierungen sollten wiederholt werden, weil sie unterschiedlichen Zwecken dienen. Die Benutzeroberfläche kann vor dem Absenden des Formulars prüfen, ob ein Pflichtfeld leer ist; die API muss es erneut prüfen, damit nur gültige Anfragen angenommen werden. Die erste Prüfung verringert Reibung, die zweite schützt die Integrität des Systems.
Es ist nicht nötig, die gesamte Domänenlogik im Frontend nachzubilden. Ist eine Regel komplex, ändert sie sich häufig oder hängt sie von Serverdaten ab, sollte ihre maßgebliche Umsetzung im Backend bleiben. Gebt einen Fehler zurück, auf den klar reagiert werden kann. Muss die Benutzeroberfläche das Ergebnis vorwegnehmen, entwerft einen Abfrage- oder Vorvalidierungsvorgang und berücksichtigt dabei, dass sich der Zustand vor dem endgültigen Vorgang ändern kann. Bei der Änderung müssen die Bedingungen erneut geprüft werden.
Die Eingabevalidierung ersetzt weder Autorisierung und Zugriffskontrollen noch Maßnahmen gegen Missbrauch. Jede Anfrage muss auf dem Server anhand des betroffenen Benutzers und der betroffenen Ressource geprüft werden. In PHP ist es sinnvoll, klare Grenzen zwischen Transportvalidierung, Anwendung der Regeln und Persistenz einzuhalten und nicht anzunehmen, dass Daten vertrauenswürdig sind, nur weil sie von einer eigenen Benutzeroberfläche gesendet wurden.
Kompatible Änderungen einführen und inkompatible abstimmen
Eine Änderung ist in der Regel kompatibel, wenn bestehende Verbraucher weiterarbeiten können, ohne ihren Code zu ändern. Das Hinzufügen eines optionalen Feldes kann kompatibel sein, sofern Clients unbekannte Felder tolerieren und das neue Feld die Bedeutung bestehender Felder nicht verändert. Eigenschaften zu entfernen oder umzubenennen, Typen zu ändern oder bisher optionale Daten verpflichtend zu machen, ist für ältere Clients meist inkompatibel.
Identifiziert vor einer Änderung des Vertrags die Verbraucher, bereitgestellten Versionen, Caches und Hintergrundprozesse, die die API aufrufen. Bei einer kompatiblen Weiterentwicklung kann der Server das neue Verhalten einführen und das bisherige vorübergehend beibehalten. Das Frontend kann die neue Funktion nutzen; wenn bestätigt wurde, dass keine älteren Verbraucher mehr vorhanden sind, lässt sich die alte Funktion nach einer ausdrücklichen Entscheidung entfernen.
Wenn sich eine Änderung nicht kompatibel umsetzen lässt, zieht eine neue Version oder einen abgestimmten Übergang mit Termin, Verantwortlichen und Kriterien für die Außerbetriebnahme in Betracht. Eine Version bietet nur dann einen Mehrwert, wenn sie die Verwaltung unterschiedlicher Verbraucher ermöglicht; jede kleinere Anpassung zu versionieren, kann mehr Aufwand als Schutz verursachen. Code bereitzustellen ist nicht unbedingt gleichbedeutend damit, eine Funktion zu aktivieren: Ihr könnt sie bereitstellen und deaktiviert lassen, bis die Tests abgeschlossen sind, oder sie schrittweise aktivieren. Diese kontrollierte Aktivierung darf nicht mit der Offenlegung von Informationen gegenüber Benutzern verwechselt werden.
Den Vertrag anhand realer Nutzungsszenarien testen
API-Tests prüfen, ob das Backend gültige Eingaben annimmt, ungültige zurückweist und die vereinbarten Schemata und Zustände zurückgibt. Frontend-Tests prüfen, ob die Benutzeroberfläche diese Antworten richtig interpretiert und die Zustände angemessen darstellt. Integrationstests führen beide Seiten gemeinsam in den wichtigen Abläufen aus: erstellen, abrufen, aktualisieren oder Fehler behandeln, je nach Produkt.
Ein Vertragstest kann konkrete Erwartungen eines Verbrauchers festlegen, ohne die gesamte Implementierung zu testen. Damit er nützlich ist, muss er in einem Prozess ausgeführt werden, der Abweichungen vor einer Veröffentlichung erkennt, und Fälle wie ein fehlendes optionales Feld, einen Validierungsfehler und eine Antwort mit verweigerter Berechtigung abdecken, sofern zutreffend. Beschreibende Verträge, beispielsweise eine API-Spezifikation, erleichtern Reviews und die Generierung von Typen, garantieren aber nicht für sich allein, dass die Implementierung sie einhält: Dafür sind Tests oder Prüfungen im Integrationsprozess erforderlich.
Wählt Szenarien anhand der tatsächlichen Vorgänge und Risiken aus, nicht nur anhand der Routenliste. Ein Endpunkt kann den richtigen Typ zurückgeben und sich bei einem Statusübergang oder einem Benutzer ohne Berechtigungen trotzdem falsch verhalten. Kombiniert automatisierte Tests mit der Prüfung von Änderungen und Observability: Clientfehler, unerwartete Antworten und Unterschiede zwischen Versionen helfen, Probleme nach der Bereitstellung zu finden.
Checkliste vor der Veröffentlichung

- Ist klar, wer den Vorgang konsumiert und welche Versionen möglicherweise noch aktiv sind?
- Sind Felder, Typen, Optionalität, Formate, Fehler und relevante Zustände dokumentiert?
- Werden Geschäftsregeln und Autorisierung im Backend durchgesetzt, auch wenn die Benutzeroberfläche entsprechende Hilfen bietet?
- Bewahrt die Änderung bestehende Verbraucher oder erfordert sie einen Übergang und eine Strategie zur Außerbetriebnahme?
- Gibt es Tests für den Vertrag und den integrierten Ablauf, einschließlich wichtiger Fehlerfälle?
- Lässt sich eine Inkompatibilität anhand von Protokollen und Metriken erkennen, ohne vertrauliche Daten offenzulegen?
- Gibt es eine sichere Möglichkeit, die Änderung zu deaktivieren oder zurückzunehmen, falls sie fehlschlägt?
Ein nützlicher Vertrag friert die Architektur nicht ein: Er begrenzt Überraschungen an der Schnittstelle zwischen Systemen. Mit klaren Verantwortlichkeiten, standardmäßig kompatiblen Änderungen und Tests, die sich auf beobachtbares Verhalten konzentrieren, können Teams getrennt bereitstellen, ohne dass jede Anpassung eine manuelle Notfallkoordination erfordert.



