Bulletproof API Design: 18 Regeln
Grace Collins
Solutions Engineer · Leapcell

1. Signatur
Um zu verhindern, dass Daten in API-Schnittstellen manipuliert werden, ist es oft notwendig, Signaturen für API-Schnittstellen zu implementieren.
Der API-Anfragende verkettet die Anfrageparameter, den Zeitstempel und den geheimen Schlüssel zu einem String und generiert dann eine Signatur (sign
) mit einem MD5- oder einem anderen Hash-Algorithmus.
Dieses sign
wird dann in die Anfrageparameter oder Header aufgenommen und an die API gesendet.
Auf der API-Gateway-Dienstseite ruft das Gateway den sign
-Wert ab und verwendet dann die gleichen Anfrageparameter, den Zeitstempel und den geheimen Schlüssel, um mit demselben MD5-Algorithmus eine weitere sign
zu generieren. Dann vergleicht es die beiden sign
-Werte.
- Wenn die beiden
sign
-Werte übereinstimmen, wird die Anfrage als gültig betrachtet, und der API-Gateway-Dienst leitet die Anfrage an das entsprechende Geschäftssystem weiter. - Wenn die beiden
sign
-Werte nicht übereinstimmen, gibt der API-Gateway-Dienst einen Signaturfehler zurück.
Warum einen Zeitstempel in die Signatur aufnehmen?
Um die Sicherheit zu erhöhen und zu verhindern, dass dieselbe Anfrage wiederholt verwendet wird, wird ein Zeitstempel in die Signatur aufgenommen. Dies reduziert auch die Wahrscheinlichkeit, dass der geheime Schlüssel geknackt wird. Jede Anfrage muss eine angemessene Gültigkeitsdauer haben, z. B. 15 Minuten.
Somit bleibt eine Anfrage 15 Minuten lang gültig. Wenn sie 15 Minuten überschreitet, gibt der API-Gateway-Dienst einen Fehler zurück, der anzeigt, dass die Anfrage abgelaufen ist.
Derzeit gibt es zwei Möglichkeiten, den geheimen Schlüssel zu generieren, der in Signaturen verwendet wird:
- Fester privater Schlüssel (
privateKey
): Beide Parteien einigen sich auf einen festen Wert als geheimen Schlüssel. - AK/SK-Schlüsselpaar: Der API-Anbieter weist ein
AK/SK
-Paar zu. DerSK
wird als geheimer Schlüssel in der Signatur verwendet, während derAK
alsaccessKey
im Anfrage-Header gesendet wird. Der API-Anbieter ruft denSK
mit demAK
ab und generiert eine neuesign
zur Validierung.
2. Verschlüsselung
In einigen Fällen übertragen API-Schnittstellen hochsensible Daten wie Benutzer-Login-Passwörter, Bankkartennummern und Überweisungsbeträge. Das Anzeigen solcher Parameter im Klartext über das öffentliche Internet ist äußerst riskant.
Um dieses Risiko zu mindern, muss eine Verschlüsselung implementiert werden.
Beispielsweise muss in einer Benutzerregistrierungsschnittstelle das Passwort verschlüsselt werden, nachdem ein Benutzer seinen Benutzernamen und sein Passwort eingegeben hat.
Ein gängiger Ansatz ist die Verwendung von AES-Symmetric-Encryption:
- Im Frontend wird das Passwort des Benutzers mit einem öffentlichen Schlüssel verschlüsselt.
- Die Registrierungs-API entschlüsselt dann das Passwort mit einem geheimen Schlüssel, führt die erforderlichen Geschäftsvalidierungen durch und verschlüsselt es erneut mit einer anderen Verschlüsselungsmethode, bevor es in der Datenbank gespeichert wird.
3. IP-Whitelist
Um die API-Sicherheit weiter zu erhöhen, kann eine IP-Whitelist implementiert werden. Selbst wenn die Signatur- oder Verschlüsselungsmechanismen kompromittiert sind, müssten Angreifer die API weiterhin von einer genehmigten IP-Adresse anfordern.
Die Lösung besteht darin, API-Anfragen basierend auf IP-Adressen zu beschränken, sodass nur Anfragen von IP-Adressen auf der Whitelist zugelassen werden.
- Wenn eine API-Anfrage von einer IP-Adresse auf der Whitelist stammt, wird sie normal verarbeitet.
- Wenn die Anfrage von einer IP-Adresse stammt, die nicht auf der Whitelist steht, wird der Zugriff sofort verweigert.
Die IP-Whitelist kann auf API-Gateway-Ebene erzwungen werden.
Interne Anwendungsserver innerhalb des Unternehmens können jedoch auch kompromittiert werden, sodass Angreifer API-Anfragen aus dem Netzwerk senden können.
Um dem entgegenzuwirken, sollte eine Web-Firewall wie ModSecurity für zusätzlichen Schutz bereitgestellt werden.
4. Ratenbegrenzung
Wenn eine Drittanbieterplattform Ihre API aufruft, kann deren Anfragehäufigkeit unkontrollierbar sein.
Wenn ein Dritter plötzlich ein riesiges Volumen an Anfragen gleichzeitig sendet, könnte dies Ihren API-Dienst überlasten und zu Ausfallzeiten führen.
Daher muss eine Ratenbegrenzung implementiert werden.
Es gibt drei gängige Ratenbegrenzungsstrategien:
-
Anfragen pro IP begrenzen Beispiel: Eine einzelne IP kann maximal 10.000 Anfragen pro Minute stellen.
-
Anfragen pro API-Endpunkt begrenzen Beispiel: Eine einzelne IP kann maximal 2.000 Anfragen pro Minute an einen bestimmten API-Endpunkt stellen.
-
Anfragen pro Benutzer (AK/SK) begrenzen Beispiel: Ein einzelner AK/SK-Benutzer kann maximal 10.000 API-Anfragen pro Minute stellen.
In realen Anwendungen kann die Ratenbegrenzung mit Nginx, Redis oder API-Gateways implementiert werden.
5. Parameter-Validierung
API-Schnittstellen müssen eine Parameter-Validierung erzwingen, wie z. B.:
- Überprüfen, ob Pflichtfelder leer sind.
- Überprüfen von Feldtypen.
- Validieren von Feldlängen.
- Sicherstellen, dass aufgezählte Werte korrekt sind.
Dies hilft, ungültige Anfragen frühzeitig im Prozess herauszufiltern und unnötige Verarbeitung zu verhindern.
Wenn beispielsweise eine Anfrage versucht, Daten einzufügen, bei denen ein Feld die maximal zulässige Länge überschreitet, würde die Datenbank einen Fehler ausgeben. Eine solche Validierung sollte jedoch vor der Datenbankoperation durchgeführt werden, um Systemressourcen zu sparen.
Beispiele für Validierungsfehler:
- Falsche Betragswerte: Wenn ein Feld positive Zahlen speichern soll, aber negative Werte akzeptiert werden, könnte dies zu unerwarteten Verlusten führen.
- Ungültige Statuswerte: Wenn das System das Statusfeld nicht validiert und ein unbekannter Wert empfangen wird, könnte dies die Datenbank beschädigen.
Häufige Validierungs-Frameworks
In Java ist das am häufigsten verwendete Validierungs-Framework Hibernate Validator, das Annotationen wie die folgenden enthält:
@Null
@NotEmpty
@Size
@Max
@Min
Diese Annotationen machen die Datenvalidierung unkompliziert.
Für Datumsfelder und Enum-Felder sind möglicherweise benutzerdefinierte Annotationen für die Validierung erforderlich.
6. Einheitliches Antwortformat
Ich bin auf APIs gestoßen, bei denen unterschiedliche Antworten inkonsistente JSON-Formate aufweisen, zum Beispiel:
Normale Antwort:
{ "code": 0, "message": null, "data": [{ "id": 123, "name": "abc" }] }
Signaturfehler-Antwort:
{ "code": 1001, "message": "Signaturfehler", "data": null }
Zugriff verweigert-Antwort:
{ "rt": 10, "errorMgt": "Keine Berechtigung", "result": null }
Warum ist das ein Problem?
Wenn eine API Antworten in verschiedenen Formaten zurückgibt, stiftet dies unnötige Verwirrung bei den Integratoren.
Dieses Problem tritt häufig auf, wenn:
- Das API-Gateway ein Antwortformat hat.
- Das Geschäftssystem ein anderes Antwortformat hat.
Wenn ein API-Gateway-Fehler auftritt, wird ein Format zurückgegeben. Wenn ein Geschäftssystemfehler auftritt, wird ein anderes Format zurückgegeben.
Die Lösung: Standardisierung von Antwortstrukturen
Das API-Gateway sollte ein einheitliches Antwortformat erzwingen.
Wenn ein Geschäftssystem eine RuntimeException mit einer Fehlermeldung auslöst, sollte das API-Gateway diese Ausnahme abfangen und in einem standardisierten Format zurückgeben.
7. Einheitliche Ausnahmebehandlung
API-Schnittstellen müssen eine konsistente Ausnahmebehandlung implementieren.
Haben Sie jemals eine Situation erlebt, in der eine API-Anfrage aufgrund eines Datenbankproblems fehlschlägt (z. B. eine fehlende Tabelle oder ein SQL-Syntaxfehler) und die Antwort direkt rohe SQL-Fehler zurückgibt?
Einige schlecht gestaltete APIs geben möglicherweise Ausnahme-Stacktraces, Datenbankdetails, Fehlercodes und sogar Zeilennummern in der Antwort aus.
Dies ist ein ernsthaftes Sicherheitsrisiko.
Bösartige Akteure könnten diese Informationen ausnutzen, um SQL-Injection-Angriffe durchzuführen oder die Datenbank direkt zu exfiltrieren, was zu Systemverletzungen führt.
Lösung: Sensible Fehlerdetails maskieren
Anstatt rohe Fehlermeldungen auszugeben, sollten alle API-Ausnahmen in eine Standardfehlerantwort umgewandelt werden, wie z. B.:
{ "code": 500, "message": "Interner Serverfehler", "data": null }
- Das Feld
code
ist500
(Standard-HTTP-Fehlercode für Serverfehler). - Das Feld
message
ist eine generische Fehlermeldung, ohne interne Systemdetails preiszugeben.
Interne Protokollierung zur Fehlerbehebung
Zur Fehlerbehebung sollten interne Protokolle weiterhin Folgendes aufzeichnen:
- Vollständige Ausnahme-Stacktraces
- Datenbankfehlerdetails
- Die genaue Fehlerzeilennummer
Dies stellt sicher, dass interne Teams über die notwendigen Informationen verfügen, um Probleme zu diagnostizieren, ohne sensible Daten an externe Benutzer weiterzugeben.
Ausnahmeabfang auf Gateway-Ebene
Die Ausnahmebehandlung kann auf API-Gateway-Ebene erzwungen werden, um sicherzustellen, dass alle Fehlerantworten einem konsistenten, bereinigten Format entsprechen.
8. Anforderungsprotokollierung
Anforderungsprotokolle sind entscheidend bei der Diagnose von Problemen mit API-Aufrufen, insbesondere für Drittanbieterplattformen.
Um die Rückverfolgbarkeit zu gewährleisten, protokollieren Sie die folgenden API-Anforderungsdetails:
- Anforderungs-URL
- Anforderungsparameter
- Anforderungsheader
- HTTP-Methode
- Antwortdaten
- Antwortzeit
Verwenden von traceId
zur Anforderungsverfolgung
Eine traceId
sollte in den Protokollen enthalten sein, damit alle zugehörigen Protokolle für eine bestimmte Anforderung miteinander verknüpft werden können. Dies hilft, irrelevante Protokolle bei der Fehlerbehebung herauszufiltern.
Protokolle für Dritte zugänglich machen
In einigen Fällen benötigen Drittanbieterplattformen möglicherweise auch Zugriff auf Anforderungsprotokolle.
Um dies zu erleichtern:
- Speichern Sie Protokolle in einer Datenbank wie MongoDB oder Elasticsearch.
- Entwickeln Sie ein UI-Dashboard, das es Drittbenutzern ermöglicht, Protokolle zu suchen und anzuzeigen.
Dies ermöglicht Self-Service-Debugging und reduziert die Notwendigkeit für externe Benutzer, sich bei kleineren Problemen an den Support zu wenden.
9. Idempotenz-Design
Eine Drittanbieterplattform kann innerhalb kürzester Zeit doppelte API-Anfragen senden, oft aufgrund von:
- Fehlern in ihrem System, die wiederholte Aufrufe verursachen.
- Wiederholungsmechanismen, wenn eine API-Antwort verzögert wird oder fehlschlägt.
Wenn eine API die Idempotenz nicht verarbeitet, könnten doppelte Anfragen zu doppelten Datensätzen führen, was zu Dateninkonsistenzen führt.
Lösung: Stellen Sie sicher, dass doppelte Anfragen keine doppelten Datensätze erstellen
Wenn dieselbe API-Anfrage mehrmals innerhalb kurzer Zeit empfangen wird:
- Die erste Anfrage wird normal verarbeitet und fügt Daten ein.
- Nachfolgende identische Anfragen fügen keine neuen Daten ein, geben aber dennoch eine Erfolgsantwort zurück.
Implementierungsansätze
-
Eindeutige Einschränkungen in der Datenbank
- Verwenden Sie einen eindeutigen Index für Anforderungsparameter, um doppelte Einträge zu verhindern.
-
Verwenden von Redis zur Deduplizierung
- Speichern Sie eine
requestId
in Redis zusammen mit Anforderungsparametern. - Wenn dieselbe
requestId
erneut empfangen wird, lehnen Sie die Anfrage ab.
- Speichern Sie eine
10. Begrenzung der Anzahl von Datensätzen in Batch-APIs
Für Batch-Verarbeitungs-APIs ist es entscheidend, die Anzahl der Datensätze pro Anfrage zu begrenzen.
Warum?
- Das Zulassen von zu vielen Datensätzen pro Anfrage kann zu API-Timeouts und Instabilität führen.
- Große Nutzlasten erhöhen die Serverlast und reduzieren die Gesamtleistung der API.
Empfohlene Grenzwerte
- Eine einzelne API-Anfrage sollte maximal 500 Datensätze zulassen.
- Wenn mehr als 500 Datensätze gesendet werden, sollte die API einen Fehler zurückgeben.
Dieser Grenzwert sollte konfigurierbar sein und mit Drittbenutzern vor der Inbetriebnahme vereinbart werden.
Paginierung für große Abfragen
Wenn eine API einen großen Datensatz zurückgeben muss, implementieren Sie die Paginierung, anstatt alle Daten in einer Anfrage zurückzugeben.
11. Lasttests
Vor dem Start einer API sind Lasttests unerlässlich, um die QPS-Grenzwerte (Abfragen pro Sekunde) zu verstehen.
Selbst wenn eine Ratenbegrenzung vorhanden ist, müssen Sie überprüfen, ob die API die erwartete Last tatsächlich bewältigen kann.
Beispielszenario
- Die API-Ratenbegrenzung ist auf 50 Anfragen pro Sekunde festgelegt.
- Die tatsächliche Serverkapazität kann jedoch nur 30 Anfragen pro Sekunde verarbeiten.
- Dies bedeutet, dass selbst bei einer Ratenbegrenzung die API immer noch abstürzen könnte.
Lasttest-Tools
- JMeter
- Apache Bench (
ab
)
Durch Ausführen von Belastungstests können Sie feststellen, wie viele Serverknoten benötigt werden, um eine stabile Leistung aufrechtzuerhalten.
12. Asynchrone Verarbeitung
Die meisten APIs sind synchron, was bedeutet, dass Anfragen sofort verarbeitet werden und Antworten in Echtzeit zurückgegeben werden.
Einige komplexe Operationen, insbesondere die Batch-Verarbeitung, können jedoch zu lange dauern, um ausgeführt zu werden.
Lösung: Konvertieren Sie lang andauernde Aufgaben in asynchrone Verarbeitung
-
Senden Sie eine MQ-Nachricht (Message Queue)
- Die API gibt sofort Erfolg zurück, nachdem die Aufgabe in die Warteschlange eingereiht wurde.
- Ein separater Nachrichten-Consumer verarbeitet die Aufgabe asynchron.
-
Lassen Sie Dritte das Verarbeitungsergebnis überprüfen
- Callback-Ansatz: Benachrichtigen Sie die Drittanbieter-API, wenn die Verarbeitung abgeschlossen ist (üblich bei Zahlungs-APIs).
- Polling-Ansatz: Der Dritte ruft wiederholt eine Statusprüfungs-API auf, um den Fortschritt zu verfolgen.
13. Datenmaskierung (Datenredaktion)
Einige API-Antworten enthalten sensible Benutzerdaten, wie z. B.:
- Telefonnummern
- Bankkartennummern
Wenn diese Informationen ohne Maskierung preisgegeben werden, erhöht dies das Risiko von Datenlecks.
Lösung: Wenden Sie Datenmaskierung an
Maskieren Sie beispielsweise Bankkartennummern:
- Original:
5196123456781234
- Maskiert:
5196****1234
Selbst wenn die Daten durchsickern, bleiben sie teilweise geschützt, was die Sicherheitsrisiken reduziert.
14. Umfassende API-Dokumentation
Gut dokumentierte APIs reduzieren den Integrationsaufwand und minimieren Fehlkommunikation.
Die API-Dokumentation sollte Folgendes enthalten:
- API-URL
- HTTP-Methode (z. B. GET, POST)
- Anforderungsparameter & Feldbeschreibungen
- Antwortformat & Feldbeschreibungen
- Fehlercodes & Meldungen
- Verschlüsselungs- & Signaturbeispiele
- Beispielanforderungen
- Zusätzliche Anforderungen (z. B. IP-Whitelist)
Standardisierung von Namenskonventionen
Um die Konsistenz zu gewährleisten:
- Verwenden Sie camelCase für Feldnamen.
- Standardisieren Sie Feldtypen & Längen (z. B.
id
alsLong
,status
alsint
). - Definieren Sie ein einheitliches Zeitformat (z. B.
yyyy-MM-dd HH:mm:ss
).
Die Dokumentation sollte auch die AK/SK-Schlüsselverwendung und API-Domänennamen angeben.
15. Anforderungsmethoden
APIs unterstützen verschiedene Anforderungsmethoden, darunter:
- GET
- POST
- PUT
- DELETE
Auswahl der richtigen Methode
- GET: Geeignet für schreibgeschützte Anfragen (wenn keine Parameter gesendet werden müssen).
- POST: Empfohlen, wenn Parameter erforderlich sind (weniger anfällig für Probleme).
Warum POST gegenüber GET verwenden?
- POST ermöglicht eine einfachere Parametererweiterung
- Bei Feign-API-Aufrufen erfordert das Hinzufügen neuer Parameter keine Änderung des vorhandenen Codes.
- GET hat ein URL-Längenlimit
- Maximal 5000 Zeichen, während POST keine Beschränkung hat.
16. Anforderungsheader
Bestimmte Parameter, wie z. B. Authentifizierungstoken oder traceId, sollten über Anforderungsheader anstelle von Abfrageparametern gesendet werden.
Zum Beispiel:
- Anstatt traceId als URL-Parameter in jeder API-Anfrage hinzuzufügen,
- Sollten Clients es im Anforderungsheader senden.
Der Server kann dann traceId mithilfe eines Interceptors extrahieren.
17. Batch-Verarbeitung
Beim Entwerfen einer API sollte immer die Batch-Verarbeitung berücksichtigt werden, unabhängig davon, ob es sich um das Abfragen, Hinzufügen, Aktualisieren oder Löschen von Daten handelt.
Warum ist die Batch-Verarbeitung wichtig?
Viele Szenarien erfordern das Abfragen mehrerer Datensätze gleichzeitig. Zum Beispiel das Abrufen von Bestelldetails:
- Wenn eine API nur das Abrufen einer Bestellung gleichzeitig unterstützt, ist für jede Bestellung ein separater API-Aufruf erforderlich.
- Wenn eine API die Batch-Abfrage unterstützt, kann eine einzelne Anfrage mehrere Bestellungen abrufen, was die Effizienz verbessert.
Ebenso beim Hinzufügen von Daten:
- Wenn eine API nur das Hinzufügen eines Datensatzes pro Anfrage unterstützt und ein Batch-Job 1.000 Datensätze einfügen muss, wären dafür 1.000 separate API-Aufrufe erforderlich.
- Stattdessen ermöglicht eine Batch-Insert-API das Senden von allen 1.000 Datensätzen in einer Anfrage, wodurch der Overhead reduziert wird.
Designempfehlung:
- Wo immer dies möglich ist, sollten APIs Batch-Operationen unterstützen, anstatt nur einzelne Datensätze zu verarbeiten.
- Dies macht APIs generischer und skalierbarer für verschiedene Geschäftsanforderungen.
18. Single Responsibility Principle
Einige API-Designs sind übermäßig komplex und unterstützen zahlreiche Bedingungen in einer einzigen Anfrage. Infolgedessen:
- Die Service-Schicht (die
Service
-Klasse) enthält übermäßig vieleif...else
-Anweisungen. - Das Antwortmodell enthält alle möglichen Felder, was zu einer überwältigenden Anzahl von Eigenschaften führt.
Das Problem bei übermäßig komplexen APIs:
- Schwer zu warten: Nach einem Jahr hat selbst der ursprüngliche Entwickler möglicherweise Schwierigkeiten, sich daran zu erinnern, welche Felder für bestimmte Szenarien erforderlich sind.
- Hohes Risiko von Änderungen, die Fehler verursachen: Das Ändern der Logik für Szenario A kann unbeabsichtigt Szenario B beeinträchtigen.
Lösung: Befolgen Sie das Single Responsibility Principle
Anstelle einer One-Size-Fits-All-API teilen Sie APIs in kleinere, szenariospezifische Endpunkte auf.
Beispiel: Für eine Bestellungs-API gibt es zwei Plattformen (Web & Mobil) und zwei Bestellmethoden (Standard & Schnell).
Anstatt eine API zu entwerfen, die alles verarbeitet, trennen Sie diese:
- Webplattform-APIs
/web/v1/order/create /web/v1/order/fastCreate
- Mobile Plattform-APIs
/mobile/v1/order/create /mobile/v1/order/fastCreate
Dies führt zu vier verschiedenen APIs, die jeweils einem bestimmten Anwendungsfall gewidmet sind. Vorteile:
- Die Geschäftslogik bleibt übersichtlich.
- APIs sind einfacher zu warten.
- Es besteht weniger Risiko unbeabsichtigter Nebenwirkungen bei Änderungen.
Fazit
Durch Befolgen dieser Best Practices werden API-Schnittstellen sicherer, skalierbarer und wartungsfreundlicher gestaltet. Diese Prinzipien helfen:
- Sicherheitslücken verhindern (z. B. unbefugter Zugriff, SQL-Injection).
- Leistung optimieren (z. B. Ratenbegrenzung, Batch-Verarbeitung).
- Entwicklererfahrung verbessern (z. B. standardisierte Antworten, klare API-Dokumentation).
Ob Sie APIs für interne Systeme oder Integrationen von Drittanbietern entwerfen, die Anwendung dieser Best Practices gewährleistet eine robustere und zukunftssicherere Architektur.
Wir sind Leapcell, Ihre erste Wahl für das Hosting von Backend-Projekten.
Leapcell ist die Next-Gen Serverless Platform für Webhosting, Async Tasks und Redis:
Multi-Sprachen Unterstützung
- Entwickeln Sie mit Node.js, Python, Go oder Rust.
Stellen Sie unbegrenzt Projekte kostenlos bereit
- Zahlen Sie nur für die Nutzung — keine Anfragen, keine Gebühren.
Unschlagbare Kosteneffizienz
- Pay-as-you-go ohne Leerlaufgebühren.
- Beispiel: 25 $ unterstützen 6,94 Mio. Anfragen mit einer durchschnittlichen Antwortzeit von 60 ms.
Optimierte Entwicklererfahrung
- Intuitive Benutzeroberfläche für mühelose Einrichtung.
- Vollständig automatisierte CI/CD-Pipelines und GitOps-Integration.
- Echtzeitmetriken und Protokollierung für umsetzbare Erkenntnisse.
Mühelose Skalierbarkeit und hohe Leistung
- Autonome Skalierung, um hohe Parallelität mühelos zu bewältigen.
- Null Betriebsaufwand — konzentrieren Sie sich einfach auf das Bauen.
Erfahren Sie mehr in der Dokumentation!
Folgen Sie uns auf X: @LeapcellHQ