Webhook vs. API: wann du abfragst und wann du benachrichtigt wirst
Webhook vs. API
Webhook vs. API: Push vs. Pull, Signaturen, Retries | We.Inc
Webhook vs. API erklärt, mit Vergleichstabelle, den Vor- und Nachteilen von Polling und Push, einem HMAC-Signaturprüfer im Browser, dem Umgang mit Retries und idempotentem Empfänger-Code.
Bei einem API-Aufruf fragt dein Code einen anderen Dienst nach Daten, wann immer er will: Das ist Pull. Bei einem Webhook sendet der Dienst einen HTTP-POST an deine URL, sobald etwas passiert: Das ist Push. Die meisten Integrationen nutzen beides, einen Webhook, um schnell von einer Änderung zu erfahren, und einen API-Aufruf, um den vollständigen, aktuellen Datensatz abzurufen.
API-Anfrage vs. Webhook
API-Anfrage (Pull)
Webhook (Push)
Wer startet
Dein Code
Der andere Dienst
Zeitpunkt
Wenn du fragst oder per Polling-Timer
Direkt nach dem Ereignis
Du brauchst
Einen API-Schlüssel und einen Client
Einen öffentlichen HTTPS-Endpunkt
Absender nachweisen
Der Anbieter prüft deinen Schlüssel
Du prüfst die Signatur des Anbieters
Wenn etwas schiefgeht
Du siehst den Fehler und versuchst es erneut
Der Anbieter versucht es erneut; du musst Duplikate behandeln
Am besten für
Daten bei Bedarf lesen oder ändern
Auf Ereignisse reagieren, die du nicht ausgelöst hast
Jede Minute eine API abzufragen, um zu sehen, ob eine Zahlung durch ist, verschwendet Anfragen und kommt trotzdem zu spät. Ein Webhook dreht die Richtung um, verlagert aber auch Verantwortung zu dir: Dein Endpunkt muss öffentlich sein, die Echtheit jeder Nachricht nachweisen, schnell antworten und damit klarkommen, dass dasselbe Ereignis zweimal eintrifft. Diese Seite behandelt jede dieser Aufgaben mit Code zum Kopieren.
Registriere beim Anbieter eine URL auf deinem Server und wähle die Ereignisse, die dich interessieren.
Der Anbieter signiert jeden Ereignis-Body mit einem gemeinsamen Geheimnis und sendet ihn per POST an diese URL.
Dein Endpunkt berechnet die Signatur über den rohen Body neu, lehnt Abweichungen ab und antwortet schnell mit 2xx.
Ein Hintergrundjob erledigt die eigentliche Arbeit und überspringt jede Ereignis-ID, die er bereits verarbeitet hat.
Prüfe gegen die rohen Bytes des Body. Wenn du JSON parst und neu serialisierst, ändern sich die Leerzeichen und die Signatur bricht.
Vergleiche Signaturen mit einer Funktion mit konstanter Laufzeit wie crypto.timingSafeEqual, niemals mit ===.
Speichere verarbeitete Ereignis-IDs mit einem Unique Constraint, damit ein Retry oder Duplikat zu einem harmlosen No-op wird.
Geh nicht davon aus, dass Ereignisse in der richtigen Reihenfolge eintreffen. Hole das aktuelle Objekt über die API, wenn die Reihenfolge wichtig ist.
Behalte einen langsamen Abgleichjob, der die API einmal täglich abfragt, um jedes Ereignis zu erwischen, das nie angekommen ist.
Häufige Fragen
Ist ein Webhook eine Art API?
Im weiteren Sinne ja. Es ist eine HTTP-Anfrage mit einem JSON-Body, nur in die entgegengesetzte Richtung gesendet. Manche nennen es eine umgekehrte API. Der entscheidende Unterschied ist, wer das Gespräch beginnt und wer online sein muss, um es zu empfangen.
Sollte ich pollen oder Webhooks verwenden?
Verwende Webhooks, wenn der Anbieter sie für die benötigten Ereignisse anbietet und du einen öffentlichen HTTPS-Endpunkt hosten kannst. Polle, wenn es keinen Webhook gibt, wenn du hinter einer Firewall sitzt oder bei wenigen Prüfungen, bei denen eine Minute Verzögerung in Ordnung ist.
Woher weiß ich, dass ein Webhook wirklich vom Anbieter kommt?
Die meisten Anbieter senden in einem Header einen HMAC SHA-256 des Body, berechnet mit einem Geheimnis, das nur du und sie kennen. GitHub verwendet zum Beispiel X-Hub-Signature-256 mit dem Präfix sha256=; Stripe verwendet Stripe-Signature mit einem Zeitstempel. Berechne ihn neu und vergleiche, bevor du irgendetwas vertraust.
Was passiert, wenn mein Endpunkt nicht erreichbar ist?
Die meisten Anbieter wiederholen fehlgeschlagene Zustellungen mit wachsenden Abständen zwischen den Versuchen, über einen Zeitraum, der vom Anbieter abhängt. Stripe zum Beispiel wiederholt Live-Ereignisse bis zu drei Tage lang. Danach ist das Ereignis nur noch über die API oder das Dashboard verfügbar.
Warum sollte ein Webhook-Handler antworten, bevor er die Arbeit erledigt?
Anbieter warten nur kurz auf eine Antwort. Wenn dein Code zuerst E-Mails verschickt oder andere Dienste aufruft, kann die Zustellung in ein Timeout laufen und wiederholt werden, obwohl du schon darauf reagiert hast. Stelle den Job in die Warteschlange, gib 200 zurück und verarbeite danach.
Pull: eine API aufrufen
Eine API-Anfrage ist eine Frage, die dein Code stellt: Gib mir Bestellung 42, liste die heutigen Anmeldungen auf, lege diesen Kunden an. Du entscheidest, wann du fragst, und bekommst sofort eine Antwort, einschließlich eines klaren Fehlers, falls etwas schiefgegangen ist.
Der Preis dafür ist, dass du von Änderungen nur erfährst, wenn du fragst. Um neue Ereignisse zu bemerken, musst du per Timer pollen, und die meisten Abfragen kommen leer zurück.
Push: einen Webhook empfangen
Bei einem Webhook ruft der Anbieter dich an. Wenn das Ereignis eintritt, sendet er per POST eine JSON-Beschreibung davon an die URL, die du registriert hast, meist innerhalb von Sekunden.
Weil jeder im Internet einen POST an diese URL senden kann, ist der Body nicht vertrauenswürdig, bis seine Signatur stimmt. Weil Netzwerke ausfallen, kann dasselbe Ereignis mehrmals oder in falscher Reihenfolge eintreffen. Ein guter Empfänger ist vom ersten Tag an auf beides ausgelegt.
Beides zusammen nutzen
Ein verbreitetes, robustes Muster behandelt den Webhook wie eine Türklingel. Er sagt dir, welches Objekt sich geändert hat; dann rufst du die API auf, liest den aktuellen Zustand dieses Objekts und handelst danach. So umgehst du Probleme mit der Reihenfolge und veraltete Payloads, und eine tägliche Abfrage erwischt alles, was die Türklingel verpasst hat.
Ein Webhook-Empfänger, der die Signatur prüft
Node und Express: HMAC SHA-256 über den rohen Body
express.raw behält den Body als Bytes, damit die Signatur passt. Dieses Header-Format folgt der sha256=-Konvention von GitHub; passe den Header-Namen für andere Anbieter an.
Retries und Duplikate behandeln
Ein Unique Index auf der Ereignis-ID lässt das Insert bei einer zweiten Zustellung fehlschlagen, sodass die Arbeit genau einmal läuft, egal wie oft das Ereignis eintrifft.
Jede Ereignis-ID einmal speichern (PostgreSQL)
ON CONFLICT DO NOTHING gibt bei einem Duplikat keine Zeile zurück, was dein Code als bereits erledigt behandelt.
Die Alternative Polling
Polling ist einfacher zu hosten, aber langsamer und gesprächiger. Führe einen Cursor mit, damit jede Abfrage nur nach Neuem fragt.
HMAC-SHA-256-Signaturprüfer
Füge einen Body und ein Geheimnis ein, um die Signatur zu berechnen, die ein Anbieter senden würde, und füge dann den empfangenen Header zum Vergleich ein. Alles läuft in deinem Browser mit der Web Crypto API; nichts wird irgendwohin gesendet.
Roher Request-Body
Webhook-Geheimnis
Signatur, die dieser Body tragen sollte
Empfangener Signatur-Header (optional)
Treffer: Body und Geheimnis ergeben diese Signatur.
Kein Treffer: Entweder hat sich der Body geändert, das Geheimnis ist falsch oder der Header nutzt ein anderes Format.