Aikido

Wie man das Brechen öffentlicher API-Verträge vermeidet: Abwärtskompatibilität aufrechterhalten

Wartbarkeit

Regel

Vermeiden Sie zu brechen. öffentlich API Verträge.
Änderungen an öffentlichen API Endpunkten die würde brechen
bestehende Kunden Anfragen sind brechen Änderungen.
Denken Sie an an die API Vertrag als a Versprechen - ändern
es nach Kunden abhängen auf es bricht ihre Code.

Unterstützte Sprachen: PHP, Java, C#, Python, JavaScript, TypeScript

Einleitung

Öffentliche APIs sind Verträge zwischen Ihrem Dienst und seinen Konsumenten. Sobald Clients vom Anforderungsformat, der Antwortstruktur oder dem Verhalten eines Endpunkts abhängen, führt eine Änderung dazu, dass ihr Code nicht mehr funktioniert. Breaking Changes zwingen alle Clients zu einer gleichzeitigen Aktualisierung, was oft unmöglich ist, wenn Sie die Clients nicht kontrollieren. Mobile Apps können nicht zwangsaktualisiert werden, Drittanbieter-Integrationen benötigen Migrationszeit, und Legacy-Systeme werden möglicherweise nie aktualisiert.

Warum es wichtig ist

Kundenbeeinträchtigung und Vertrauen: Breaking API Changes führen zu sofortigen Fehlern in produktiven Client-Anwendungen. Nutzer erleben Fehler, Datenverlust oder komplette Serviceausfälle. Dies schädigt das Vertrauen zwischen API-Anbietern und -Konsumenten und verletzt den impliziten Vertrag, dass stabile APIs stabil bleiben.

Koordinationskosten: Die Koordination von Breaking Changes über mehrere Client-Teams hinweg ist teuer und langsam. Jedes Team benötigt Zeit, um Code zu aktualisieren, Änderungen zu testen und zu deployen. Bei öffentlichen APIs mit unbekannten Clients (mobile Apps, Drittanbieter-Integrationen) ist eine Koordination unmöglich.

Versionsproliferation: Schlecht verwaltete Breaking Changes führen dazu, dass mehrere API-Versionen gleichzeitig gepflegt werden müssen. Jede Version erfordert separate Codepfade, Tests, Dokumentationen und Bugfixes, was den Wartungsaufwand exponentiell erhöht.

Code-Beispiele

❌ Nicht konform:

// Version 1: Original API
app.get('/api/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({ id: user.id, name: user.name });
});

// Version 2: Breaking change - renamed field
app.get('/api/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({
        id: user.id,
        fullName: user.name  // Breaking: 'name' renamed to 'fullName'
    });
});

Warum es falsch ist: Das Umbenennen von name in fullName führt dazu, dass alle bestehenden Clients, die das Feld name erwarten, nicht mehr funktionieren. Client-Code, der auf response.name zugreift, erhält undefined, was zu Fehlern führt. Diese Änderung zwingt alle Clients, gleichzeitig zu aktualisieren oder fehlzuschlagen.

✅ Konform:

// Version 2: Additive change - keeps old field, adds new
app.get('/api/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({
        id: user.id,
        name: user.name,           // Keep for backward compatibility
        fullName: user.name        // Add new field (deprecated 'name')
    });
});

// Or use API versioning
app.get('/api/v2/users/:id', async (req, res) => {
    const user = await db.users.findById(req.params.id);
    res.json({ id: user.id, fullName: user.name });
});

Warum dies wichtig ist: Das Alte beibehalten Name Das Feld wahrt die Abwärtskompatibilität und fügt hinzu vollständiger Name für neue Kunden. Alternativ kann ein neuer versionierter Endpunkt erstellt werden (/api/v2/) ermöglicht Breaking Changes, ohne bestehende Clients zu beeinträchtigen, die noch /api/v1/.

Fazit

APIs durch additive Änderungen weiterentwickeln: neue Felder, neue Endpunkte und optionale Parameter hinzufügen. Wenn Breaking Changes unvermeidlich sind, API-Versionierung nutzen, um alte und neue Versionen gleichzeitig zu betreiben. Alte Felder mit klaren Zeitplänen und Migrationsleitfäden als veraltet kennzeichnen, bevor sie entfernt werden.

FAQs

Haben Sie Fragen?

Welche Änderungen gelten als Breaking Changes?

Entfernen von Feldern aus Antworten, Umbenennen von Feldern, Ändern von Feldtypen (String zu Zahl), optionale Parameter zu Pflichtparametern machen, Ändern von HTTP-Statuscodes für bestehende Bedingungen, Ändern von Authentifizierungsanforderungen und Anpassen von Fehlerantwortformaten. Das Hinzufügen neuer erforderlicher Anfrageparameter oder das vollständige Entfernen von Endpunkten sind ebenfalls Breaking Changes.

Wie füge ich neue Pflichtfelder hinzu, ohne Clients zu beeinträchtigen?

Machen Sie das neue Feld anfänglich optional mit einem sinnvollen Standardwert. Dokumentieren Sie die Änderung und geben Sie Kunden Zeit zur Anpassung. Nach ausreichender Zeit (6-12 Monate für öffentliche APIs) machen Sie das Feld in einer neuen API-Version obligatorisch. Machen Sie niemals bestehende optionale Felder ohne Versionierung obligatorisch.

Was ist der Unterschied zwischen API-Versioning und Deprecation?

Versioning erstellt einen neuen Endpunkt (/v2/users) neben dem alten, sodass beide koexistieren können. Deprecation kennzeichnet einen alten Endpunkt oder ein Feld als veraltet, hält es aber funktionsfähig, mit einem Zeitplan für die eventuelle Entfernung. Verwenden Sie Versioning für größere Änderungen, Deprecation für den schrittweisen Ausstieg aus kleineren Funktionen.

Wie lange sollte ich veraltete API-Versionen pflegen?

Für öffentliche APIs pflegen Sie veraltete Versionen für mindestens 12-18 Monate. Für interne APIs stimmen Sie sich mit den Client-Teams bezüglich eines Migrationszeitplans ab. Geben Sie immer eine Vorankündigung (mindestens 3-6 Monate) vor dem Entfernen veralteter Endpunkte. Überwachen Sie Nutzungsmetriken, um sicherzustellen, dass Clients vor der Abschaltung migriert sind.

Kann ich die Reihenfolge der Antwortfelder ändern?

Ja, die Reihenfolge der JSON-Objektfelder ist nicht Teil des API-Vertrags. Gut geschriebene Clients parsen JSON nach Feldnamen, nicht nach Position. Testen Sie jedoch gründlich, da einige schlecht geschriebene Clients von der Feldreihenfolge abhängen könnten. Bei Arrays ist die Reihenfolge normalerweise wichtig und sollte sich nicht ändern, es sei denn, dies ist dokumentiert.

Wie versioniere ich APIs ohne Änderungen am URL-Pfad?

Verwenden Sie HTTP-Header: Accept: application/vnd.myapi.v2+json oder benutzerdefinierte Header wie API-Version: 2. Query-Parameter funktionieren ebenfalls: /api/users?version=2. Content Negotiation über Header ist sauberer, aber in Browsern schwieriger zu testen. Wählen Sie eine Strategie und wenden Sie diese konsequent an.

Werden Sie jetzt sicher.

Sichern Sie Ihren Code, Ihre Cloud und Ihre Laufzeit in einem zentralen System.
Finden und beheben Sie Schwachstellen schnell und automatisch.

Keine Kreditkarte erforderlich | Scan-Ergebnisse in 32 Sek.