Ereignisgesteuerte Workflows vs. Request-Response-APIs für lang laufende Aufgaben
Vergleich ereignisgesteuerter Workflows und Request-Response-APIs für lang laufende Prozesse mit Fokus auf Genehmigungen, Timer, Retries und Audit-Trails in Business-Apps.

Warum lang laufende Prozesse in Business-Apps knifflig sind
Ein Prozess ist „lang laufend“, wenn er nicht in einem schnellen Schritt fertig wird. Er kann Minuten, Stunden oder Tage dauern, weil er von Menschen, Zeit oder externen Systemen abhängt. Alles mit Genehmigungen, Übergaben und Warten fällt in diesen Bereich.
Genau hier beginnt das einfache Request-Response-Denken zu versagen. Ein API-Aufruf ist für einen kurzen Austausch gebaut: Anfrage senden, Antwort bekommen, weitermachen. Lange Aufgaben sind eher eine Geschichte mit Kapiteln. Du musst pausieren, genau merken, wo du bist, und später ohne Rätsel wieder aufnehmen.
Das sieht man in alltäglichen Business-Apps: Freigaben für Einkäufe, die Manager und Finanzwesen brauchen; Onboarding, das auf Dokumentenprüfungen wartet; Rückerstattungen, die von einem Zahlungsanbieter abhängen; oder Zugriffsanfragen, die geprüft und dann angewendet werden müssen.
Wenn Teams einen langen Prozess wie einen einzigen API-Aufruf behandeln, tauchen einige vorhersehbare Probleme auf:
- Die App verliert Zustand nach einem Restart oder Deploy und kann nicht zuverlässig weitermachen.
- Retries erzeugen Duplikate: eine zweite Zahlung, eine zweite E-Mail, eine doppelte Genehmigung.
- Zuständigkeiten werden unklar: Wer macht als Nächstes — der Anforderer, ein Manager oder ein Systemjob?
- Support hat keine Transparenz und kann nicht einfach beantworten „wo hängt es?“ ohne Logs zu wälzen.
- Warten-Logik (Timer, Erinnerungen, Deadlines) endet als fragile Hintergrundskripte.
Ein konkretes Szenario: Ein Mitarbeiter beantragt Softwarezugang. Der Manager genehmigt schnell, aber die IT braucht zwei Tage zur Bereitstellung. Wenn die App den Prozesszustand nicht halten, Erinnerungen senden und sicher fortsetzen kann, entstehen manuelle Nachfragen, verwirrte Nutzer und zusätzliche Arbeit.
Deshalb ist die Wahl zwischen ereignisgesteuerten Workflows und Request-Response-APIs für lang laufende Geschäftsprozesse so wichtig.
Zwei Denkmodelle: synchrone Aufrufe vs. Ereignisse über Zeit
Die einfachste Gegenüberstellung reduziert sich auf eine Frage: Wird die Arbeit beendet, während der Nutzer wartet, oder läuft sie weiter, nachdem er gegangen ist?
Eine Request-Response-API ist ein einzelner Austausch: ein Call rein, eine Antwort raus. Sie passt zu Arbeit, die schnell und vorhersehbar fertig wird, wie das Anlegen eines Datensatzes, das Berechnen eines Angebots oder das Prüfen von Lagerbestand. Der Server macht die Arbeit, gibt Erfolg oder Fehler zurück, und die Interaktion ist beendet.
Ein ereignisgesteuerter Workflow ist eine Serie von Reaktionen über die Zeit. Etwas passiert (eine Bestellung wird angelegt, ein Manager genehmigt, ein Timer läuft ab) und der Workflow geht zum nächsten Schritt. Dieses Modell passt zu Arbeit mit Übergaben, Warten, Retries und Erinnerungen.
Der praktische Unterschied ist Zustand.
Bei Request-Response lebt Zustand oft in der aktuellen Anfrage plus Server-Speicher, bis die Antwort gesendet ist. Bei ereignisgesteuerten Workflows muss Zustand persistiert werden (z. B. in PostgreSQL), damit der Prozess später wieder aufgenommen werden kann.
Auch die Fehlerbehandlung ändert sich. Request-Response behandelt Fehler meist, indem ein Fehler zurückgegeben und der Client zum erneuten Versuch aufgefordert wird. Workflows zeichnen den Fehler auf und können sicher erneut versuchen, wenn sich die Bedingungen verbessern. Sie können zudem jeden Schritt als Ereignis protokollieren, was die Historie rekonstruiert.
Ein einfaches Beispiel: „Spesenabrechnung einreichen“ kann synchron sein. „Genehmigung einholen, 3 Tage warten, Manager erinnern, dann auszahlen“ ist es nicht.
Genehmigungen: wie jeder Ansatz menschliche Entscheidungen handhabt
Genehmigungen sind der Punkt, an dem lang laufende Arbeit real wird. Ein Systemschritt ist in Millisekunden fertig, aber ein Mensch antwortet in zwei Minuten oder zwei Tagen. Die zentrale Designentscheidung ist, ob du dieses Warten als pausierten Prozess modelierst oder als neue Nachricht, die später ankommt.
Bei Request-Response-APIs nehmen Genehmigungen oft eine unbequeme Form an:
- Blockieren (nicht praktikabel)
- Polling (der Client fragt immer wieder „genehmigt?“)
- Callbacks/Webhooks (der Server ruft später zurück)
All das kann funktionieren, aber es fügt Infrastruktur hinzu, nur um menschliche Zeit mit API-Zeit zu überbrücken.
Mit Events liest sich die Genehmigung wie eine Geschichte. Die App protokolliert etwas wie „ExpenseSubmitted“ und erhält später „ExpenseApproved“ oder „ExpenseRejected“. Die Workflow-Engine (oder deine eigene Zustandsmaschine) bewegt den Datensatz erst weiter, wenn das nächste Ereignis eintrifft. Das entspricht dem, wie die meisten Menschen bereits an Geschäftsschritte denken: einreichen, prüfen, entscheiden.
Komplexität taucht schnell auf bei mehreren Entscheidern und Eskalationsregeln. Vielleicht sind Manager und Finanzwesen erforderlich, und ein Senior Manager kann überstimmen. Wenn du diese Regeln nicht klar modellierst, wird der Prozess schwer nachvollziehbar und noch schwerer zu auditieren.
Ein einfaches Genehmigungsmodell, das skaliert
Ein praktisches Muster ist, eine einzelne „Anfrage“-Entität zu behalten und Entscheidungen separat zu speichern. So unterstützt du viele Genehmiger, ohne die Kernlogik umzuschreiben.
Erfasse ein paar Daten als erstklassige Datensätze:
- Die Genehmigungsanfrage selbst: was genehmigt wird und der aktuelle Status
- Einzelne Entscheidungen: wer entschieden hat, genehmigt/abgelehnt, Zeitstempel, Grund
- Die erforderlichen Genehmiger: Rolle oder Person und etwaige Reihenfolgeregeln
- Ergebnisregeln: „jedes einzelne“, „Mehrheit“, „alle erforderlich“, „Override erlaubt"
Egal für welche Implementierung du dich entscheidest: speichere immer, wer was wann und warum genehmigt hat, als Daten und nicht nur als Logzeile.
Timer und Warten: Erinnerungen, Deadlines und Eskalationen
Warten ist der Punkt, an dem lange Tasks chaotisch werden. Leute gehen in die Mittagspause, Kalender füllen sich, und „wir melden uns“ wird zu „wer ist jetzt zuständig?“ Das ist einer der klarsten Unterschiede zwischen ereignisgesteuerten Workflows und Request-Response-APIs.
Bei Request-Response-APIs ist Zeit unhandlich. HTTP-Aufrufe haben Timeouts, du kannst also keine Anfrage zwei Tage offenhalten. Teams landen oft bei Mustern wie Polling, einem separaten Scheduled-Job, der die DB scannt, oder manuellen Skripten, wenn etwas überfällig ist. Das funktioniert, aber die Warte-Logik lebt außerhalb des Prozesses. Randfälle sind leicht zu übersehen, z. B. wenn der Job zweimal läuft oder sich der Datensatz kurz vor der Erinnerung geändert hat.
Workflows behandeln Zeit als normalen Schritt. Du kannst sagen: warte 24 Stunden, sende eine Erinnerung, dann warte insgesamt 48 Stunden und eskaliere an einen anderen Genehmiger. Das System behält Zustand, sodass Deadlines nicht in einem separaten „cron + queries“-Projekt versteckt sind.
Eine einfache Regel könnte so lauten:
Nach Einreichung einer Spesenabrechnung warte 1 Tag. Wenn der Status immer noch „Pending“ ist, benachrichtige den Manager. Nach 2 Tagen, falls noch pending, weise es dem Vorgesetzten des Managers zu und protokolliere die Eskalation.
Der entscheidende Punkt ist, was du tust, wenn der Timer auslöst, sich die Welt aber geändert hat. Ein guter Workflow überprüft vor dem Handeln den aktuellen Zustand:
- Lade den neuesten Status
- Bestätige, dass er noch „Pending“ ist
- Prüfe, ob der Zuständige noch gültig ist (Teams ändern sich)
- Protokolliere, was du entschieden hast und warum
Retries und Fehlerwiederherstellung ohne doppelte Aktionen
Retries sind das, was du tust, wenn etwas aus Gründen, die du nicht voll kontrollierst, schiefgeht: ein Zahlungs-Gateway setzt aus, ein E-Mail-Provider meldet einen temporären Fehler oder deine App speichert Schritt A, stürzt aber vor Schritt B ab. Die Gefahr ist einfach: Beim Wiederholen wird die Aktion versehentlich doppelt ausgeführt.
Bei Request-Response-APIs ist das übliche Muster, dass der Client einen Endpoint aufruft, wartet und bei unklarem Erfolg erneut anfragt. Damit das sicher ist, muss der Server wiederholte Calls als dieselbe Absicht behandeln.
Eine praktische Lösung ist ein Idempotency-Key: Der Client sendet ein eindeutiges Token wie pay:invoice-583:attempt-1. Der Server speichert das Ergebnis für diesen Key und liefert bei Wiederholungen dasselbe Resultat. Das verhindert doppelte Belastungen, doppelte Tickets oder doppelte Genehmigungen.
Ereignisgesteuerte Workflows haben ein anderes Duplikat-Risiko. Events werden oft mindestens einmal zugestellt, das heißt Duplikate können auch bei korrektem Betrieb auftauchen. Konsumenten müssen deduplizieren: speichere die Event-ID (oder einen Geschäftsschlüssel wie invoice_id + step) und ignoriere Wiederholungen. Das ist ein zentraler Unterschied: Request-Response konzentriert sich auf sichere Wiederholungen von Aufrufen, Events auf sichere Wiederholungen von Nachrichten.
Ein paar Retry-Regeln funktionieren in beiden Modellen gut:
- Nutze Backoff (z. B. 10s, 30s, 2m).
- Setze eine maximale Anzahl an Versuchen.
- Trenne temporäre Fehler (retry) von permanenten Fehlern (sofort fehlschlagen).
- Leite wiederholte Fehler in einen „Benötigt Aufmerksamkeit“-Zustand.
- Logge jeden Versuch, damit du später erklären kannst, was passiert ist.
Retries sollten explizit im Prozess sein, nicht verstecktes Verhalten. So machst du Fehler sichtbar und behebbbar.
Audit-Trails: den Prozess erklärbar machen
Ein Audit-Trail ist deine „Warum“-Akten. Wenn jemand fragt: „Warum wurde diese Ausgabe abgelehnt?“, solltest du antworten können, ohne zu raten, selbst Monate später. Das ist in beiden Ansätzen wichtig, aber die Arbeit sieht anders aus.
Für jeden lang laufenden Prozess protokolliere die Fakten, die es erlauben, die Geschichte nachzuspielen:
- Akteur: wer hat gehandelt (Benutzer, Service oder System-Timer)
- Zeit: wann es passierte (mit Zeitzone)
- Eingaben: was damals bekannt war (Betrag, Anbieter, Policy-Grenzen, Genehmigungen)
- Ergebnis: welche Entscheidung oder Aktion stattfand (genehmigt, abgelehnt, bezahlt, erneut versucht)
- Regelversion: welche Policy-/Logikversion verwendet wurde
Ereignisgesteuerte Workflows können Audits erleichtern, weil jeder Schritt natürlich ein Ereignis wie „ManagerApproved“ oder „PaymentFailed“ erzeugt. Wenn du diese Events mit Payload und Akteur speicherst, erhältst du eine saubere Timeline. Wichtig ist, Events beschreibend zu halten und sie an einem Ort zu speichern, den du nach Fällen abfragen kannst.
Request-Response-APIs sind ebenfalls auditierbar, aber die Geschichte ist oft über Services verstreut. Ein Endpoint loggt „genehmigt“, ein anderer loggt „Zahlung angefordert“, ein dritter loggt „Retry erfolgreich“. Wenn jedes anders formatiert ist, wird Auditing zur Detektivarbeit.
Eine einfache Lösung ist eine gemeinsame „Case ID“ (auch Korrelations-ID genannt). Hänge sie an jede Anfrage, jedes Event und jeden DB-Eintrag für die Prozessinstanz, z. B. EXP-2026-00173. Dann kannst du die gesamte Reise über Schritte hinweg nachverfolgen.
Den richtigen Ansatz wählen: Stärken und Kompromisse
Die beste Wahl hängt davon ab, ob du sofort eine Antwort brauchst oder ob der Prozess über Stunden oder Tage weiterlaufen muss.
Request-Response funktioniert gut, wenn die Arbeit kurz ist und die Regeln einfach. Ein Nutzer reicht ein Formular ein, der Server validiert, speichert und gibt Erfolg oder Fehler zurück. Es passt auch zu klaren, einzelnen Aktionen wie Create, Update oder Permission-Checks.
Es wird problematisch, wenn ein „einzelner Request“ heimlich viele Schritte wird: Warten auf Genehmigung, Aufrufe mehrerer externer Systeme, Umgang mit Timeouts oder Verzweigungen. Entweder hältst du eine Verbindung offen (fragil), oder du schiebst Warten und Retries in schwer nachvollziehbare Hintergrundjobs.
Ereignisgesteuerte Workflows glänzen, wenn der Prozess eine Geschichte über Zeit ist. Jeder Schritt reagiert auf ein neues Event (genehmigt, abgelehnt, Timer ausgelöst, Zahlung fehlgeschlagen) und entscheidet, was als Nächstes passiert. Das macht Pausieren, Fortsetzen, Retry und eine klare Begründung leichter.
Es gibt echte Kompromisse:
- Einfachheit vs. Dauerhaftigkeit: Request-Response ist einfacher zu starten, ereignisgesteuert ist robuster für lange Verzögerungen.
- Debugging-Stil: Request-Response folgt einer geraden Linie, Workflows erfordern oft eine Trace über Schritte.
- Tools und Gewohnheiten: Events brauchen gutes Logging, Korrelations-IDs und klare Zustandsmodelle.
- Change-Management: Workflows entwickeln sich und verzweigen; gut modelliert handhaben ereignisgesteuerte Designs neue Pfade besser.
Ein praktisches Beispiel: Eine Spesenabrechnung, die Manager, dann Finanzprüfung und schließlich Auszahlung braucht. Wenn die Zahlung fehlschlägt, willst du Retries ohne Doppelzahlung. Das ist natürlich ereignisgesteuert. Wenn es nur „Spesen einreichen“ mit schnellen Checks ist, reicht Request-Response häufig aus.
Schritt-für-Schritt: Einen lang laufenden Prozess so entwerfen, dass er Verzögerungen übersteht
Lang laufende Geschäftsprozesse scheitern auf langweilige Weise: Ein Browser-Tab schließt, ein Server startet neu, eine Genehmigung liegt drei Tage, oder ein Zahlungsprovider timeout-t. Entwerfe von Anfang an für diese Verzögerungen — egal welches Modell du bevorzugst.
Beginne damit, eine kleine Menge Zustände zu definieren, die du speichern und wiederherstellen kannst. Wenn du nicht aus der Datenbank den aktuellen Zustand benennen kannst, hast du keinen wirklich wiederaufnehmbaren Workflow.
Eine einfache Design-Abfolge
- Grenzen setzen: definiere Trigger-Start, Endbedingung und ein paar Schlüsselzustände (Pending approval, Approved, Rejected, Expired, Completed).
- Events und Entscheidungen benennen: schreibe auf, was im Laufe der Zeit passieren kann (Submitted, Approved, Rejected, TimerFired, RetryScheduled). Verwende Vergangenheitsform für Event-Namen.
- Wartepunkte wählen: identifiziere, wo der Prozess für einen Menschen, ein externes System oder eine Deadline pausiert.
- Timer- und Retry-Regeln pro Schritt hinzufügen: entscheide, was passiert, wenn Zeit vergeht oder ein Call fehlschlägt (Backoff, max attempts, eskalieren, aufgeben).
- Definiere, wie der Prozess wieder aufgenommen wird: Bei jedem Event oder Callback lade gespeicherten Zustand, verifiziere, dass er noch gültig ist, und gehe dann zum nächsten Zustand.
Um Neustarts zu überstehen, persistiere die minimalen Daten, die du zum sicheren Weitermachen brauchst. Speicher genug, um ohne Ratespiel erneut auszuführen:
- Prozess-Instanz-ID und aktuellen Zustand
- Wer als Nächstes handeln kann (Assignee/Rolle) und was er entschieden hat
- Deadlines (due_at, remind_at) und Eskalations-Level
- Retry-Metadaten (Anzahl Versuche, letzter Fehler, next_retry_at)
- Idempotency-Key oder „bereits erledigt“-Flags für Seiteneffekte (Nachricht gesendet, Karte belastet)
Wenn du rekonstruieren kannst „wo wir sind“ und „was als Nächstes erlaubt ist“ aus gespeicherten Daten, hören Verzögerungen auf, angsteinflößend zu sein.
Häufige Fehler und wie man sie vermeidet
Lang laufende Prozesse brechen meist erst, wenn echte Nutzer auftauchen. Eine Genehmigung braucht zwei Tage, ein Retry feuert zur falschen Zeit, und du hast eine doppelte Zahlung oder eine fehlende Audit-Spur.
Häufige Fehler:
- Eine HTTP-Anfrage offen halten, während auf eine menschliche Genehmigung gewartet wird. Sie läuft aus, bindet Ressourcen und vermittelt dem Nutzer fälschlich, dass „etwas passiert“.
- Calls ohne Idempotenz zu wiederholen. Ein Netzwerkausfall wird so zur doppelten Rechnung, doppelten E-Mail oder wiederholten „Approved“-Transition.
- Prozesszustand nicht zu speichern. Wenn Zustand im Speicher liegt, löscht ein Restart ihn. Wenn Zustand nur in Logs steht, kannst du nicht zuverlässig weitermachen.
- Eine unsaubere Audit-Spur. Events haben unterschiedliche Zeitstempel und Formate, sodass die Timeline bei Vorfällen oder Compliance-Reviews nicht vertrauenswürdig ist.
- Async und Sync mixen ohne eine Quelle der Wahrheit. Ein System sagt „Paid“, ein anderes „Pending“ — und niemand weiß, was stimmt.
Ein Beispiel: Eine Spesenabrechnung wird im Chat genehmigt, ein Webhook kommt verspätet, und die Zahlungs-API wird erneut versucht. Ohne gespeicherten Zustand und Idempotenz kann der Retry die Zahlung zweimal ausführen, und deine Daten erklären nicht klar, warum.
Die meisten Lösungen sind explizit:
- Persistiere Zustandsübergänge (Requested, Approved, Rejected, Paid) in einer Datenbank mit wer/was sie geändert hat.
- Nutze Idempotency-Keys für externe Nebenwirkungen (Zahlungen, E-Mails, Tickets) und speichere das Ergebnis.
- Trenne „Anfrage annehmen“ von „Arbeit abschließen“: antworte schnell, und führe den Workflow dann im Hintergrund fort.
- Standardisiere Zeitstempel (UTC), füge Korrelations-IDs hinzu und speichere sowohl Anfrage als auch Ergebnis.
Kurze Checkliste bevor du baust
Lang laufende Arbeit dreht sich weniger um einen perfekten Call und mehr darum, nach Verzögerungen, Menschen und Fehlern korrekt zu bleiben.
Schreibe auf, was „sicher fortsetzen“ für deinen Prozess bedeutet. Wenn die App mitten im Prozess neu startet, solltest du ohne Raten am letzten bekannten Schritt anknüpfen können.
Eine praktische Checkliste:
- Definiere, wie der Prozess nach Crash oder Deploy weitergeht. Welcher Zustand ist gespeichert und was läuft als Nächstes?
- Gib jeder Instanz einen eindeutigen Process-Key (z. B. ExpenseRequest-10482) und ein klares Statusmodell (Submitted, Waiting for Manager, Approved, Paid, Failed).
- Behandle Genehmigungen als Datensätze, nicht nur als Outcomes: wer genehmigt/abgelehnt hat, wann und mit welchem Kommentar/Grund.
- Mappe Warte-Regeln: Erinnerungen, Deadlines, Eskalationen, Verfallszeiten. Benenne einen Owner für jeden Timer (Manager, Finance, System).
- Plane Fehlerbehandlung: Retries müssen begrenzt und sicher sein, und es sollte einen „needs review“-Stopp geben, wo ein Mensch Daten korrigieren oder einen erneuten Versuch genehmigen kann.
Ein Sanity-Test: Stell dir vor, ein Payment-Provider time-outet, nachdem du die Karte bereits belastet hast. Dein Design sollte doppelte Belastungen verhindern und trotzdem den Prozess abschließen lassen.
Beispiel: Spesenfreigabe mit Deadline und Zahlungs-Retry
Szenario: Ein Mitarbeiter reicht eine Taxiquittung über 120 $ ein. Sie braucht innerhalb von 48 Stunden die Genehmigung des Managers. Nach Genehmigung zahlt das System an den Mitarbeiter aus. Wenn die Zahlung fehlschlägt, wird sicher erneut versucht und alles bleibt klar protokolliert.
Request-Response-Durchlauf
Bei Request-Response-APIs verhält sich die App oft wie ein Gespräch, das ständig nachhaken muss.
Der Mitarbeiter tippt auf „Submit“. Der Server legt einen Erstattungsdatensatz mit Status „Pending approval“ an und gibt eine ID zurück. Der Manager bekommt eine Benachrichtigung, aber die Mitarbeiter-App muss in der Regel poll-en, um Änderungen zu sehen, z. B. „GET reimbursement status by ID“.
Um die 48-Stunden-Deadline durchzusetzen, betreibst du entweder einen geplanten Job, der überfällige Anfragen scannt, oder du speicherst einen Deadline-Timestamp und prüfst ihn bei jedem Poll. Wenn der Job verspätet läuft, sieht der Nutzer veralteten Status.
Wenn der Manager genehmigt, setzt der Server den Status auf „Approved“ und ruft den Zahlungsanbieter auf. Wenn Stripe einen temporären Fehler liefert, muss der Server entscheiden, ob jetzt, später oder gar nicht erneut versucht wird. Ohne sorgfältige Idempotency-Keys kann ein Retry zu doppelter Auszahlung führen.
Ereignisgesteuerter Durchlauf
Im ereignisgesteuerten Modell wird jede Änderung als Fakt gespeichert.
Der Mitarbeiter reicht ein, es entsteht ein "ExpenseSubmitted"-Event. Ein Workflow startet und wartet entweder auf "ManagerApproved" oder auf ein Timer-Event "DeadlineReached" nach 48 Stunden. Wenn der Timer zuerst auslöst, protokolliert der Workflow eine "AutoRejected"-Ausgabe mit Begründung.
Bei Genehmigung protokolliert der Workflow "PayoutRequested" und versucht zu zahlen. Wenn Stripe time-outet, protokolliert er "PayoutFailed" mit Fehlercode, plant einen Retry (z. B. in 15 Minuten) und protokolliert erst nach einer einmaligen, idempotenten Bestätigung "PayoutSucceeded".
Was der Nutzer sieht, bleibt einfach:
- Pending approval (noch 48 Stunden)
- Genehmigt, Auszahlung läuft
- Zahlungs-Retry geplant
- Ausgezahlt
Die Audit-Trail liest sich wie eine Timeline: submitted, approved, deadline geprüft, payout versucht, fehlgeschlagen, erneut versucht, bezahlt.
Nächste Schritte: Das Modell in eine funktionierende App überführen
Wähle einen echten Prozess und baue ihn vollständig durch, bevor du generalisierst. Spesenfreigabe, Onboarding und Rückerstattungen sind gute Starter, weil sie menschliche Schritte, Warten und Fehlerpfade enthalten. Halte das Ziel klein: ein Hauptpfad und die zwei häufigsten Ausnahmen.
Schreibe den Prozess als Zustände und Events, nicht als Screens. Zum Beispiel: „Submitted" -> "ManagerApproved" -> "PaymentRequested" -> "Paid", mit Verzweigungen wie "ApprovalRejected" oder "PaymentFailed". Wenn Wartepunkte und Seiteneffekte klar sind, wird die Wahl zwischen ereignisgesteuerten Workflows und Request-Response-APIs praktisch.
Entscheide, wo der Prozesszustand liegt. Eine Datenbank reicht aus, wenn der Flow einfach ist und du Updates an einem Ort erzwingen kannst. Eine Workflow-Engine hilft, wenn du Timer, Retries und Verzweigungen brauchst, weil sie verfolgt, was als Nächstes passieren soll.
Füge Audit-Felder von Anfang an hinzu. Speicher, wer was getan hat, wann es passierte und warum (Kommentar oder Fehlercode). Wenn jemand fragt: „Warum wurde diese Zahlung erneut versucht?“, willst du eine klare Antwort ohne Log-Recherche.
Wenn du so einen Workflow in einer No-Code-Plattform baust, ist AppMaster (appmaster.io) eine Option, mit der du Daten in PostgreSQL modellieren und Prozesslogik visuell aufbauen kannst — das kann Genehmigungen und Audit-Trails über Web- und Mobile-Apps hinweg konsistenter halten.
FAQ
Verwende Request-Response, wenn die Arbeit schnell und vorhersehbar fertig wird, während der Nutzer wartet — zum Beispiel beim Erstellen eines Datensatzes oder Validieren eines Formulars. Nutze ein ereignisgesteuertes Workflow-Modell, wenn der Prozess Minuten bis Tage dauert, Menschenentscheidungen, Timer, Retries oder sicheres Fortsetzen nach Neustarts umfasst.
Lang laufende Aufgaben passen nicht in einen einzelnen HTTP-Aufruf: Verbindungen laufen aus, Server starten neu, und oft hängt die Arbeit von Menschen oder externen Diensten ab. Wenn du alles wie einen einzigen Call behandelst, verlierst du Zustand, erzeugst Duplikate bei Retries und verteilst Wartelogik auf verstreute Hintergrundjobs.
Speichere einen klaren Prozesszustand in der Datenbank und lasse ihn nur durch explizite Übergänge fortschreiten. Bewahre die Prozess-ID, den aktuellen Status, wer als Nächstes handeln kann und die relevanten Zeitstempel, damit du nach Deploys, Abstürzen oder Verzögerungen sicher weitermachen kannst.
Modelliere Genehmigungen als pausierten Schritt, der erst weiterläuft, wenn eine Entscheidung eintrifft — statt zu blockieren oder ständig zu poll-en. Speichere jede Entscheidung als Datenpunkt (wer, wann, genehmigt/abgelehnt, Grund), damit der Workflow vorhersehbar weiterläuft und auditierbar bleibt.
Polling kann für einfache Fälle funktionieren, erzeugt aber zusätzlichen Verkehr und Verzögerungen, weil der Client ständig fragt „Ist es fertig?“. Besser ist es, Änderungen zu pushen und den Client bei Bedarf zu aktualisieren, während der Server als Quelle der Wahrheit dient.
Behandle Zeit als Teil des Prozesses: speichere Deadlines und Erinnerungszeiten und überprüfe beim Auslösen eines Timers zuerst den aktuellen Zustand, bevor du handelst. So vermeidest du Erinnerungen, nachdem schon genehmigt wurde, und behältst Konsistenz, auch wenn Jobs verspätet oder doppelt laufen.
Verwende Idempotency-Keys für jede Nebenwirkung wie Kartenzahlungen oder E-Mails und speichere das Ergebnis für diesen Schlüssel. Dann sind Retries sicher, weil dieselbe Absicht wiederholt denselben Resultat zurückgibt, statt die Aktion erneut auszuführen.
Gehe davon aus, dass Nachrichten mehrmals zugestellt werden können, und designe Konsumenten zur Deduplizierung. Speichere die Ereignis-ID (oder einen geschäftlichen Schlüssel für den Schritt) und ignoriere Wiederholungen, damit ein Replay nicht dieselbe Aktion erneut auslöst.
Erfasse eine Fakten-Timeline: Akteur, Zeitstempel, die damals bekannten Eingaben, das Ergebnis und die verwendete Regel-/Policy-Version. Nutze zusätzlich eine einzelne Case- oder Korrelations-ID, die du an alle Requests, Events und Datenbankeinträge hängst, damit Support den Prozess ohne langes Suchen rekonstruieren kann.
Behalte eine Anfrage als „Fall“ und speichere Entscheidungen separat; lasse Zustandsänderungen durch persistente Übergänge laufen, die wieder abgespielt werden können. In No-Code-Werkzeugen wie AppMaster kannst du Daten in PostgreSQL modellieren und die Schritt-Logik visuell umsetzen, was Genehmigungen, Retries und Audit-Felder konsistent hält.


