Platform

Czym jest idempotentność i jak obsługiwać zduplikowane webhooki?

Idempotentność sprawia, że powtórzona operacja daje ten sam efekt co jedna operacja, więc obsługuj zduplikowane webhooki bez powielania ich pracy.

Zerwane połączenie może pozostawić Cię w niepewności, czy żądanie wysyłki się powiodło. Utracone potwierdzenie może też spowodować, że nadawca webhooka dostarczy zdarzenie, które Twoja aplikacja już zapisała.

Te awarie zachodzą w przeciwnych kierunkach. Bird może rozpoznać powtórzone żądanie API za pomocą klucza, który podajesz. Twój odbiornik webhooków potrzebuje własnego rejestru zdarzeń, które już przyjął.

Jak bezpiecznie ponowić wysyłkę?

Używaj tego samego nagłówka Idempotency-Key dla każdej próby jednej logicznej operacji API.

Sam wybierasz klucz o długości do 255 znaków i zachowujesz go między ponowieniami. Stabilna wartość taka jak welcome-user/usr_abc123 może identyfikować operację wiadomości powitalnej nawet po restarcie procesu.

Nagłówek dotyczy żądań mutujących, takich jak POST, PATCH i DELETE. Żądanie bez klucza jest przetwarzane bez tej deduplikacji. GET ignoruje nagłówek, ponieważ odczyt zasobu jest bezpieczny do powtórzenia.

Bird zwraca zapisaną odpowiedź dla pasującego ukończonego żądania, łącznie z oryginalnym statusem i ciałem. Odpowiedź zawiera Idempotency-Replay: true, więc możesz zidentyfikować to ponowne użycie w swoich logach.

Przewodnik po idempotentności dokumentuje domyślne trzymiesięczne okno dla ukończonej odpowiedzi. Ponowienie po jego wygaśnięciu może zostać wykonane jako nowa operacja. Nie polegaj na tym kluczu na stałe, aby zapobiec zduplikowanym wysyłkom.

SDK Bird generują klucz dla mutacji i używają go ponownie w swoich wewnętrznych ponowieniach. Bird CLI również generuje klucz dla żądania mutującego, gdy jest on nieobecny. Ustaw --idempotency-key jawnie, gdy oddzielne wywołania poleceń muszą współdzielić tę samą operację.

W przypadku przesyłania SMTP użyj nagłówka wiadomości X-Bird-Idempotency-Key. Pozwala to ponowionemu przesłaniu zidentyfikować tę samą operację.

Co się stanie, jeśli użyję klucza nieprawidłowo?

Bird odrzuca kolidujące użycie klucza zamiast zwracać odpowiedź dla innej operacji.

SytuacjaOdpowiedź i naprawa
Ten sam klucz i żądanie po ukończeniuZapisana odpowiedź, z Idempotency-Replay: true.
Ukończony klucz użyty ponownie dla innego żądania409 z E01005, oznaczające ponowne użycie klucza idempotentności. Popraw klucz przed ponowieniem.
Inne żądanie z tym kluczem wciąż trwa409 z E01004, oznaczające żądanie w toku. Poczekaj chwilę i spróbuj ponownie.
Klucz przekracza 255 znaków400 z E01002, oznaczające nieprawidłowe dane wejściowe. Skróć klucz.

Porównanie obejmuje metodę, endpoint, parametry ścieżki, ciąg zapytania i ciało. W przypadku JSON zmiana białych znaków zmienia tożsamość żądania, więc zachowaj oryginalne ciało podczas ponowień.

Blokada na niedokończonej operacji wygasa w ciągu trzydziestu sekund. Ten limit pozwala innemu żądaniu kontynuować po porzuconej operacji. Nie ustala, czy efekt uboczny już wystąpił.

Bird nie zapisuje odpowiedzi 5xx do odtworzenia. Ponów błąd serwera lub timeout z tym samym kluczem, aby zapisany sukces mógł być nadal wykorzystany.

Odrzucenie z powodu walidacji lub reguły biznesowej zwalnia klucz. Możesz poprawić odrzucone żądanie i ponowić je z tym samym kluczem, ponieważ żadna ukończona odpowiedź nie została zachowana.

Dlaczego dostaję ten sam webhook dwa razy?

Bird może ponowić zdarzenie, które Twój odbiornik już zapisał, jeśli nie otrzyma pomyślnej odpowiedzi.

Odbiornik może zapisać zdarzenie tuż przed zerwaniem połączenia. Bird nie widzi pomyślnego potwierdzenia i ponawia, mimo że odbiornik już ma to zdarzenie.

Każde ponowienie zachowuje ten sam nagłówek webhook-id, który identyfikuje zdarzenie. Odtworzenie pominiętego dostarczenia również zachowuje ten identyfikator, więc oba mogą być rozpoznane jako to samo zdarzenie.

Jak uczynić mój handler idempotentnym?

Zapisuj każdy webhook-id z unikalnym ograniczeniem bazodanowym przed zaplanowaniem pracy dla zdarzenia.

Sprawdzanie istniejącego wiersza przed wstawieniem pozostawia wyścig: dwa równoczesne żądania mogą nie zobaczyć żadnego wiersza. Pozwól bazie danych odrzucić zduplikowane identyfikatory.

Zapisz identyfikator i zadanie w tej samej transakcji. Zapobiega to zarejestrowaniu identyfikatora bez zakolejkowania żadnej pracy.

  1. Zweryfikuj żądanie, a następnie wstaw jego identyfikator i zadanie w tej samej transakcji.
  2. Zwróć 2xx po zatwierdzeniu transakcji, aby Bird mógł przestać ponawiać.
  3. Przetwarzaj zapisane zadanie w workerze, który może bezpiecznie powtarzać własne akcje.

Jeśli zduplikowany identyfikator jest już zatwierdzony, zwróć sukces bez tworzenia kolejnego zadania. W przypadku nieudanej transakcji zwróć błąd, aby Bird ponowił próbę.

Nie umieszczaj wolnej pracy w odbiorniku, ponieważ oczekiwanie na nią może spowodować przekroczenie limitu czasu żądania. Worker może ponawiać z przyczyn niezwiązanych z dostarczaniem webhooków, więc ochrona samego odbiornika jest niewystarczająca.

Zdarzenia mogą też przychodzić w niewłaściwej kolejności. Porównuj czasy zdarzeń w timestamp przed nadpisaniem nowszego stanu. Ponowienia nieudanych webhooków zawierają przykład częściowego kosztu.

Na czym nie powinno się polegać?

Nie zakładaj, że deduplikacja żądań uniemożliwia zduplikowane efekty uboczne.

Jeśli magazyn deduplikacji Bird jest niedostępny, żądania są przetwarzane bez niego. Utrzymuj zabezpieczenie na poziomie biznesowym tam, gdzie powtórzenie akcji byłoby szkodliwe.

Podobnie webhook-id rozróżnia powtórzone dostarczenia jednego zdarzenia. Oddzielne zdarzenia mają oddzielne identyfikatory. Twoja aplikacja nadal decyduje, czy te zdarzenia uzasadniają powtórzenie tej samej akcji.

Idempotentność dokumentuje zachowanie ponowień API. Webhooki obejmują oddzielne gwarancje dostarczenia, które obsługuje Twój odbiornik.

W skrócie

  1. Ponowienia żądań do API i ponowienia webhooków wymagają różnych rekordów.

    Używaj ponownie Idempotency-Key w żądaniach do Bird. Twój odbiornik zapisuje webhook-id, aby rozpoznać zdarzenie, które już przyjął.

  2. Odrzucone żądania mogą zwolnić swoje klucze.

    Błędy walidacji i reguł biznesowych nie tworzą ukończonej odpowiedzi, co pozwala na poprawione ponowienie z tym samym kluczem.

  3. Ukończony klucz nie może identyfikować innych żądań.

    Zmienione ciało żądania lub endpoint JSON może spowodować konflikt 409. Popraw klucz zamiast ponawiać ten konflikt bez zmian.

  4. Deduplikacja ma ograniczenia.

    Żądania są przetwarzane, gdy magazyn deduplikacji jest niedostępny. Zadbaj, by powtórzone akcje były bezpieczne również w Twojej aplikacji.

Buduj na tej samej sieci.

Testowy klucz API otrzymasz od razu. Dostęp produkcyjny odblokujesz po dodaniu metody płatności i zweryfikowaniu nadawcy.

Twój kolejny pomysł.
Gotowy do połączenia.