Zapisy w API to mutacje GraphQL wysyłane na ten sam adres co zapytania. Każda mutacja wymaga zakresu zapisu z jej strony w referencji, a zapisane zmiany widać w Prynt z integracją jako autorem.
Problem: niepewny wynik
Dział zatytułowany „Problem: niepewny wynik”Połączenie może zerwać się po wysłaniu mutacji, ale przed odebraniem odpowiedzi. Nie wiesz wtedy, czy
zapis się wykonał. Ponowienie bez zabezpieczenia może utworzyć drugi taki sam obiekt, np. drugie
zamówienie. Nagłówek Idempotency-Key rozwiązuje ten problem: żądanie ponowione z tym samym kluczem
w ciągu 24 h nie wykona się drugi raz (w normalnych warunkach pracy API, zobacz zasady
niżej).
Nagłówek Idempotency-Key
Dział zatytułowany „Nagłówek Idempotency-Key”Przykłady pokazują adres zastępczy. Wpisz adres swojej drukarni, żeby go podmienić.
-
Przed wysłaniem mutacji wygeneruj klucz, najlepiej UUID, i zapisz go razem z operacją, którą wykonujesz (np. przy zamówieniu w Twoim sklepie).
-
Wyślij mutację z nagłówkiem
Idempotency-Key:Okno terminala IDEMPOTENCY_KEY=$(uuidgen) # zapisz go, zanim wyślesz żądaniecurl -sS https://twoja-drukarnia.prynt.pl/api/v1/graphql \-H "Authorization: Bearer $PRYNT_API_KEY" \-H "Content-Type: application/json" \-H "Idempotency-Key: $IDEMPOTENCY_KEY" \--data-binary @mutacja.json -
Gdy nie dostaniesz odpowiedzi, wyślij to samo żądanie z tym samym kluczem. Jeśli pierwsze się wykonało, API zwróci jego zapisaną odpowiedź z nagłówkiem
Idempotent-Replayed: truei niczego nie zapisze ponownie.
- Wartość klucza: od 1 do 255 drukowalnych znaków ASCII. Inaczej API odpowiada
błędem
API_IDEMPOTENCY_KEY_INVALID. - Tylko mutacje. Zapytania ignorują nagłówek: odczyt można ponawiać bez niego.
- Jeden klucz, jedna operacja. Nowa operacja zawsze dostaje nowy klucz. Klucze każdej integracji są liczone osobno.
- 24 h. API pamięta klucz przez 24 h od zakończenia mutacji. Po tym czasie ten sam klucz działa jak nowy, więc późniejsze ponowienie może wykonać zapis drugi raz.
- Długie mutacje. Mutacja, która trwa dłużej niż 60 minut, przestaje po tym czasie chronić swój klucz: ponowienie może ją wtedy wykonać drugi raz.
- Gdy Prynt nie może pamiętać kluczy. Jeśli przy chwilowej awarii API nie może zarezerwować
klucza przed wykonaniem mutacji, nie wykonuje jej: odpowiada statusem HTTP 503 i błędem
API_IDEMPOTENCY_UNAVAILABLE. Nic się wtedy nie zapisało, więc ponów żądanie później z tym samym kluczem i tą samą treścią. Mutacja bez nagłówkaIdempotency-Keywykonuje się w takiej sytuacji normalnie, bez ochrony. - Normalne warunki pracy. Ochronę zapewniamy w normalnych warunkach pracy API. Przy awarii po
stronie Prynt w trakcie mutacji albo tuż po niej API może nie zapamiętać klucza, nawet gdy
dostaniesz zwykłą odpowiedź: ponowienie przez kilka minut dostaje
API_IDEMPOTENCY_IN_PROGRESS, a potem może wykonać mutację drugi raz. Dlatego integracja, dla której duplikat byłby kosztowny, po takim ponowieniu sprawdza zapytaniem, czy go nie ma. - Ta sama treść. Żądania są „takie same”, gdy mają tę samą operację, nazwę operacji i zmienne.
Formatowanie i komentarze w zapytaniu ani kolejność kluczy w
variablesnie mają znaczenia; każda inna zmiana tak.
Odpowiedzi na powtórzony klucz
Dział zatytułowany „Odpowiedzi na powtórzony klucz”Konflikty mają status HTTP 409, a mutacja nie jest wtedy wykonywana.
| Sytuacja | Odpowiedź |
|---|---|
| Mutacja z tym kluczem już się wykonała, ta sama treść | Zapisana odpowiedź pierwszego żądania i nagłówek Idempotent-Replayed: true. |
| Mutacja z tym kluczem jeszcze trwa | CONFLICT, API_IDEMPOTENCY_IN_PROGRESS. Ponów za chwilę z tym samym kluczem. |
| Klucz był użyty z inną treścią | CONFLICT, API_IDEMPOTENCY_KEY_REUSED. To błąd w kodzie integracji: nowa operacja, nowy klucz. |
| Mutacja się wykonała, ale odpowiedź miała około 64 KiB lub więcej | CONFLICT, API_IDEMPOTENCY_RESPONSE_TOO_LARGE. Nie ponawiaj; pobierz wynik zapytaniem. |
Kiedy odpowiedź jest zapamiętana
Dział zatytułowany „Kiedy odpowiedź jest zapamiętana”API zapamiętuje odpowiedź zawsze, gdy mutacja mogła coś zapisać: przy sukcesie i przy częściowym sukcesie, gdy obok danych są błędy. Powtórka zwraca wtedy te same dane i te same błędy.
Klucz jest zwalniany tylko wtedy, gdy odpowiedź dowodzi, że nic się nie wykonało: żądanie odrzucono przed wykonaniem (np. błąd zapytania, brak zakresu, przekroczony limit) albo jedyna mutacja w żądaniu zakończyła się błędem. Możesz wtedy poprawić żądanie i wysłać je z tym samym kluczem.
Wysyłaj jedną mutację na żądanie. Gdy żądanie ma kilka mutacji i jedna z nich zakończy się błędem, API nie może wykluczyć, że pozostałe coś zapisały: klucz zostaje zajęty, a powtórka zwraca tę samą odpowiedź z błędem.
Zmiana rekordu: pole pominięte, null
Dział zatytułowany „Zmiana rekordu: pole pominięte, null”Mutacje zmieniające rekord, np. updateOrder, updateClient czy updateClientAddress, to łatki:
w ich typie wejścia każde pole jest opcjonalne, a pole, którego nie wysyłasz, zostaje bez zmian.
null czyści pole tylko tam, gdzie opis pola w referencji to podaje (np. telefon klienta); w
pozostałych polach API go odrzuca błędem walidacji. Dlatego puste wartości ze swojego systemu
pomijaj, a null wysyłaj tylko wtedy, gdy chcesz pole wyczyścić. Poprawność rekordu API sprawdza
po zmianie: firma zachowuje NIP, a kod pocztowy adresu musi pasować do kraju, który adres ma po
zmianie. Tak samo zmieniasz operację zamówienia (updateOperation): jej zasady i odmowy opisuje
Technologia zamówienia.
Własny identyfikator rekordu
Dział zatytułowany „Własny identyfikator rekordu”Idempotency-Key chroni jedno wywołanie przez 24 h. Żeby na stałe powiązać rekord w
Prynt z rekordem w swoim systemie, nadaj mu własny identyfikator w polu externalRef (dziś: klient
i zamówienie zakupu).
Przy kolejnej synchronizacji znajdziesz po nim rekord filtrem externalRef i zapiszesz go
mutacją zmiany zamiast tworzyć drugi (upsert). Identyfikator jest unikalny i widoczny tylko w
obrębie Twojej integracji: inna integracja ma własne identyfikatory tych samych rekordów. Przykłady:
Klienci do CRM i z powrotem i Zamówienie zakupu z systemu
dostawcy.
Ponawianie
Dział zatytułowany „Ponawianie”Ponawiaj tylko błędy przejściowe, z rosnącym odstępem:
| Ponawiaj | Nie ponawiaj bez zmian w żądaniu |
|---|---|
| Błąd sieci, przekroczony czas oczekiwania, odpowiedź HTTP 5xx | VALIDATION, BAD_REQUEST |
INTERNAL |
UNAUTHENTICATED, FORBIDDEN |
RATE_LIMITED — po czasie z nagłówka Retry-After |
NOT_FOUND |
API_IDEMPOTENCY_IN_PROGRESS, API_IDEMPOTENCY_UNAVAILABLE |
Pozostałe CONFLICT |
- Odstęp rośnie wykładniczo z losowym rozrzutem, np. 1, 2, 4, 8 sekund, najwyżej 30 sekund i kilka prób.
- Ponowiona mutacja ma ten sam
Idempotency-Keyi tę samą treść. - Gotowy kod w czterech językach: Obsługa błędów i ponowień.