Idempotence
Les réseaux tombent au pire moment : vous envoyez un POST, la connexion se coupe et vous ne savez pas si l'e-mail est parti. L'idempotence vous permet de réessayer cette requête en toute sécurité. Renvoyez le même en-tête Idempotency-Key et Bird rejoue la réponse d'origine au lieu de traiter la requête une seconde fois.
Fonctionnement
L'idempotence est optionnelle. Ajoutez un en-tête Idempotency-Key à une requête POST, PATCH, PUT ou DELETE prise en charge. Les requêtes sans cet en-tête sont traitées normalement, sans déduplication. Les requêtes GET ignorent l'en-tête.
Sur l'API client, les mutations limitées à l'espace de travail ou à l'organisation prennent en charge le rejeu de réponse décrit ci-dessous. Les opérations réservées à l'utilisateur, les opérations non authentifiées sans portée et les flux le contournent. Les opérations dotées d'un contrat de rejeu distinct définissent leur comportement dans leur page de référence. Par exemple, Créer un appel vocal conserve l'instantané d'acceptation d'origine pour les réessais correspondants lorsque vous fournissez une clé.
Les SDK génèrent une clé pour chaque appel mutatif et la réutilisent pour les réessais automatiques, y compris la création d'appel. Vous n'avez pas besoin d'en fournir une pour les réessais SDK automatiques. Fournissez la vôtre lorsqu'une même opération logique couvre plusieurs appels SDK distincts, par exemple un réessai après le redémarrage de votre application. Ces exemples illustrent ce cas.
await bird.email.send(
{
from: "hello@yourdomain.com",
to: ["delivered@messagebird.dev"],
subject: "Welcome!",
html: "<p>Thanks for signing up.</p>",
},
{ idempotencyKey: "welcome-user/usr_abc123" },
);client.email.send(
from_="hello@yourdomain.com",
to=["delivered@messagebird.dev"],
subject="Welcome!",
html="<p>Thanks for signing up.</p>",
options={"idempotency_key": "welcome-user/usr_abc123"},
)_, err := client.Email.Send(context.Background(), bird.EmailSendParams{
From: "hello@yourdomain.com",
To: []string{"delivered@messagebird.dev"},
Subject: "Welcome!",
HTML: "<p>Thanks for signing up.</p>",
}, option.WithIdempotencyKey("welcome-user/usr_abc123"))$bird->email->send(
from: 'hello@yourdomain.com',
to: ['delivered@messagebird.dev'],
subject: 'Welcome!',
html: '<p>Thanks for signing up.</p>',
options: new RequestOptions(idempotencyKey: 'welcome-user/usr_abc123'),
);curl -X POST https://us1.platform.bird.com/v1/email/messages \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: welcome-user/usr_abc123" \
-d '{
"from": "hello@yourdomain.com",
"to": ["delivered@messagebird.dev"],
"subject": "Welcome!",
"html": "<p>Thanks for signing up.</p>"
}'Une clé est une chaîne non vide de 255 caractères maximum. Une valeur d'en-tête vide désactive la déduplication. Le format recommandé est une clé déterministe dérivée de vos propres entités, <event-type>/<entity-id> (par exemple welcome-user/usr_abc123), afin que les réessais après un redémarrage de processus partagent la même clé ; un UUID aléatoire par opération logique fonctionne aussi. Les SDK Bird génèrent automatiquement une clé UUID pour chaque requête mutative et la réutilisent lors de leurs réessais internes.
Les clés sont rattachées à votre espace de travail, ou à votre organisation pour les endpoints au niveau de l'organisation. Une réponse complétée est conservée pendant 3 heures ; une tentative après cette fenêtre est traitée comme une nouvelle requête. La fenêtre couvre les planifications de réessai habituelles. Aucun enregistrement de déduplication ne subsiste après son expiration.
Rejeux
Lorsque Bird voit une clé déjà complétée, il renvoie la réponse en cache, même code de statut, même corps, sans réexécuter la requête. Les réponses rejouées portent un en-tête supplémentaire pour les distinguer d'un traitement initial :
Exemple de code
HTTP/1.1 202 Accepted
Idempotency-Replay: trueLes réponses conservées peuvent inclure des rejets 4xx. Utilisez une nouvelle clé lorsque vous corrigez une requête : si son rejet a été conservé, une nouvelle tentative identique le rejoue, et une requête modifiée renvoie 409 E01005 IdempotencyKeyReuse. Les réponses 5xx ne sont pas conservées ; réessayez-les avec la même clé et la même requête.
Modes d'échec
| Scénario | Réponse |
|---|---|
| Même clé, même requête, originale terminée | Réponse en cache rejouée avec Idempotency-Replay: true |
| Même clé, corps de requête ou point de terminaison différent | 409, E01005 IdempotencyKeyReuse |
| Même clé, requête originale encore en cours | 409, E01004 RequestInProgress |
| Clé de plus de 255 caractères sur un point de terminaison déclarant l'en-tête | 422, E01001 ValidationError |
| Protection d'idempotence indisponible avant l'exécution | 503, E01033 IdempotencyUnavailable ; cette tentative n'est pas exécutée |
Réutiliser une clé terminée avec une requête différente est traité comme un bug client : Bird renvoie 409 immédiatement plutôt que de vous remettre silencieusement une réponse qui ne correspond pas à ce que vous avez envoyé. Générez une nouvelle clé pour la nouvelle requête. La comparaison porte sur la méthode, le point de terminaison, le chemin et les paramètres de requête, ainsi que le corps brut de la requête, y compris les espaces JSON. Les téléversements multipart comparent les noms de parties, les noms de fichiers et les contenus ; les délimiteurs et l'ordre des parties n'affectent pas le rejeu.
RequestInProgress signifie qu'une requête concurrente avec la même clé n'a pas encore abouti, généralement parce qu'un délai d'attente trop court côté client relance la requête alors que la première tentative est encore en cours. Le verrou en vol expire dans les 30 secondes : attendez brièvement et réessayez. Consultez Erreurs pour la réponse d'erreur qui les enveloppe.
Ce qui n'est pas mis en cache
Les réponses 5xx ne sont jamais mises en cache. La clé se déverrouille et Bird peut traiter une nouvelle tentative comme un nouvel essai. Réessayez les réponses 5xx et les délais d'attente dépassés avec un backoff en utilisant la même clé et la même requête. Une opération peut prendre effet avant que sa réponse ne soit enregistrée ; si cette réponse est perdue ou si le verrou en vol expire, une nouvelle tentative peut exécuter l'opération à nouveau.
Si la protection d'idempotence est indisponible avant l'exécution, l'API renvoie 503 E01033 IdempotencyUnavailable sans exécuter cette tentative. Conservez la clé à chaque nouvelle tentative. Cette erreur ne décrit pas le résultat d'une tentative antérieure avec la même clé.
Conseils pratiques
- Générez une clé par opération logique et réutilisez-la à chaque tentative HTTP de cette opération.
- Réessayez en cas d'erreurs réseau, de délais d'attente dépassés et de 5xx avec un backoff exponentiel, en réutilisant la même clé à chaque fois.
- Considérez 409 IdempotencyKeyReuse comme un bogue dans votre génération de clés. Ne réessayez pas.
- Les clés sont facultatives sur les mutations. Utilisez-en une lorsque vous avez besoin d'une protection contre les réessais ; omettez-la sur les requêtes GET.
Étapes suivantes
- Référence API de l'idempotence : schémas de l'en-tête et de l'en-tête de réponse
- Concepts SDK : génération automatique des clés et comportement de réessai dans les SDK
- Erreurs : la réponse d'erreur et le catalogue de codes
- Envoi d'e-mails : endpoints d'envoi et d'envoi par lot
Ressources associées
Poursuivez avec la documentation, les guides et les exemples sur ce sujet. Les ressources sont en anglais.