Przejdź do treści
Workin'FlowsBlog → Outbox pattern w n8n
n8n

Outbox pattern w n8n: API nie z webhooka

Adrian Krawczyk opublikowane ostatnia aktualizacja 5 min czytania

Outbox pattern w n8n to jedna z tych rzeczy, które brzmią jak architektura dla ludzi w polarach z konferencji, a potem okazuje się, że ratują Ci tyłek przy zwykłym formularzu kontaktowym.

Klasyczny scenariusz, który idzie w bengier

Masz webhook w n8n. Wpada lead. Ty od razu z webhooka wołasz CRM, fakturownię, Slacka, mailing, arkusz, może jeszcze API od kuriera, bo czemu nie. Wszystko działa na testach. Pięknie. Bengier.

A potem zewnętrzne API ma czkawkę. CRM odpowiada po 28 sekundach. Fakturujący SaaS zwraca 502. Slack przyjmuje wiadomość, ale workflow pada na następnym kroku. Lead niby był. Ale gdzie jest prawda? W n8n? W CRM? W mailingu? U Pana Boga w kajecie?

No właśnie.

W tym artykule pokażę Ci, czemu nie wołam zewnętrznego API prosto z webhooka, jak rozkładam taki proces w n8n i jak używam outbox pattern bez robienia z tego doktoratu. To jest tekst dla osób, które robią automatyzacje w n8n, zbierają dane z formularzy, budują integracje między systemami albo mają już dość jojczenia, że "czasem coś się nie wysłało".

Czym jest outbox pattern w n8n?

Outbox pattern w n8n to podejście, w którym webhook najpierw zapisuje zdarzenie do trwałego miejsca, a dopiero osobny workflow wysyła dane do zewnętrznych API.

Czyli nie robisz tak:

  1. Webhook przyjmuje dane.
  2. Webhook od razu woła CRM.
  3. Webhook od razu woła mailing.
  4. Webhook od razu woła Slacka.
  5. Webhook czeka, aż cały świat łaskawie odpowie.

Tylko tak:

  1. Webhook przyjmuje dane.
  2. Webhook waliduje minimum.
  3. Webhook zapisuje event do tabeli outbox.
  4. Webhook szybko zwraca odpowiedź.
  5. Osobny workflow bierze event z outboxa.
  6. Osobny workflow woła CRM, mailing, Slacka i resztę ferajny.
  7. Status eventu jest aktualizowany.
Outbox pattern oddziela przyjęcie zdarzenia od jego dostarczenia do zewnętrznych systemów.

I to jest cała magia. Nie potrzebujesz bębna szamańskiego ani 12 mikroserwisów. W n8n wystarczy sensownie rozdzielić odpowiedzialności. Webhook ma przyjąć dane. Worker ma je przetworzyć. Tyle.

Czemu nie wołam zewnętrznego API prosto z webhooka?

Nie wołam zewnętrznego API prosto z webhooka, bo webhook powinien być szybki, przewidywalny i możliwie głupi. "Głupi" to komplement.

Webhook to recepcja w hotelu. Ma przyjąć gościa, sprawdzić rezerwację, dać klucz i nie robić przy tym pięciu telefonów do pralni, kuchni, księgowości i instruktora jogi.

Jeżeli z webhooka od razu wołasz zewnętrzne API, podpisujesz stabilność swojego procesu pod dostępność każdego z tych serwisów naraz. Jeden odpowiada wolno, reszta czeka. Jeden pada, cały webhook pada. Lead ginie, bo fakturujący SaaS miał chwilę. I ty wiesz o tym dopiero gdy klient zadzwoni.

Outbox pattern izoluje to ryzyko. Webhook przyjmuje dane i odpowiada szybko. Dane są w bazie, bezpieczne. Worker robi resztę i może retry gdy API nie odpowiada. Klient dostaje potwierdzenie, zanim cokolwiek pójdzie do CRM.

Tabela outbox: minimal viable schema

W n8n używam Postgres jako outboxa. Minimalna tabela wygląda tak:

CREATE TABLE outbox (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  event_type  TEXT NOT NULL,
  payload     JSONB NOT NULL,
  status      TEXT NOT NULL DEFAULT 'pending',
  attempts    INT  NOT NULL DEFAULT 0,
  created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
  processed_at TIMESTAMPTZ
);

Status: pending, processing, done, failed. Worker bierze eventy w statusie pending, ustawia processing, robi robotę, ustawia done albo po kilku próbach failed.

Ważne Inkrementuj attempts przy każdej próbie. Jeśli worker pada w środku, event wraca do pending i jest próbowany ponownie. Bez licznika prób skończyłbyś z eventem próbowanym w nieskończoność.

Jak to śmiga w n8n: dwa workflowy

Workflow 1: receiver (webhook)

  1. Webhook node przyjmuje POST.
  2. Function node waliduje wymagane pola (email, typ eventu).
  3. Postgres node: INSERT do outbox ze statusem pending.
  4. Respond to Webhook: HTTP 200 z {"status":"queued"}.

Cały flow to sekund ułamek. Nie czeka na CRM, nie czeka na mailing. Dane są bezpieczne.

Workflow 2: worker (cron co minutę albo trigger)

  1. Postgres node: SELECT z outbox WHERE status='pending' LIMIT 10.
  2. Postgres node: UPDATE status na processing, inkrementuj attempts.
  3. Switch node po event_type: inna ścieżka dla leada, inna dla zamówienia.
  4. HTTP Request do CRM, mailingowego, Slacka.
  5. Postgres node: UPDATE status na done, zapisz processed_at.
  6. Error handler: jeśli HTTP rzucił wyjątek i attempts >= 3, ustaw failed.

Worker jest niezależny od receivera. Restart receivera, błąd w nim, nic z tego nie gubi eventów z outboxa. Dane już tam są.

Kiedy to stosować, a kiedy nie

Outbox pattern ma sens gdy:

Nie stosuj outboxa gdy:

Przy synchronicznych odpowiedziach i tak możesz ogarniać część logiki asynchronicznie: odpowiedz natychmiast tym co masz, a wysyłkę maila i zapis do CRM wrzuć do outboxa.

Z doświadczenia Tabela outbox to przy okazji darmowy audit log. Widzisz kiedy co przyszło, ile prób zajęło, co zrobiło status failed. Przy debugowaniu integracji to jest fest przydatne, szczególnie gdy klient mówi "wpłaciłem, ale nie dostałem dostępu".

Najczęstsze pytania

Czym jest outbox pattern w n8n?

Outbox pattern w n8n to podejście, w którym webhook najpierw zapisuje zdarzenie do trwałej tabeli w bazie, a dopiero osobny workflow wysyła dane do zewnętrznych API. Oddziela przyjęcie zdarzenia od jego dostarczenia, dzięki czemu awaria zewnętrznego serwisu nie niszczy procesu przyjmowania danych.

Dlaczego nie wołać zewnętrznego API prosto z webhooka n8n?

Bo podpisujesz stabilność swojego procesu pod dostępność zewnętrznych serwisów. Jeśli CRM odpowiada po 28 sekundach albo mailing SaaS zwraca 502, Twój webhook czeka, timeout, lead ginie. Outbox pattern izoluje te ryzyka: webhook jest szybki i niezawodny, a dostarczanie do zewnętrznych API to zadanie workera z retry.

Chcesz webhooki, które nie gubią danych?

U Ciebie zaczynam od warsztatu procesu (90 minut, bezpłatny). Rozrysujemy przepływ integracji i powiem wprost, gdzie są słabe punkty. Bez wciskania jednego słusznego stacku.

Zamów warsztat → Lub napisz bezpośrednio.
Nota o procesie: Szkic artykułu powstał z udziałem agenta AI w ramach Workin'Agency. Redakcja merytoryczna, weryfikacja techniczna i zatwierdzenie: Adrian Krawczyk. (AI Act, Art. 50)