Erreurs
Un document problème lisible par machine pour chaque échec, et ce que chaque type implique pour votre logique de nouvelle tentative.
Chaque échec — y compris une route qui n'existe pas — répond en
application/problem+json, la forme définie par la RFC 9457. Aucun chemin dans
cette API ne renvoie de page d'erreur HTML : un analyseur qui suppose du JSON
sur une réponse non 2xx est donc en sécurité.
{
"type": "https://api.backresto.com/problems/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "The authenticated client lacks the required scope.",
"instance": "/v1/restaurants/restaurant-1/deliveries/8f2c/images",
"requestId": "b1c8b0a4-6c1e-4f6b-9e1c-3b2a5d7f0e91"
}
type est l'identifiant stable : branchez dessus, pas sur detail, qui est de
la prose et peut être reformulé. requestId est la valeur à citer dans un
message au support — elle est aussi renvoyée dans l'en-tête de réponse
X-Request-ID, et vous pouvez définir cet en-tête vous-même pour faire le lien
avec vos propres traces.
Le catalogue
Suffixe de type | Statut | Ce qui s'est passé | Réessayer ? |
|---|---|---|---|
invalid-request | 400 | Un paramètre est manquant ou mal formé : une plage de livraisons inversée ou trop longue, une collection inconnue, ou un curseur qui ne correspond pas au restaurant, à la collection et au limit avec lesquels vous paginez. | Non — corrigez la requête. |
unauthorized | 401 | Pas d'en-tête Authorization, ou une clé mal formée, inconnue, révoquée, expirée, ou qui n'a plus aucune autorisation. | Non — la clé demande votre attention. |
forbidden | 403 | La clé détient une autorisation pour ce restaurant mais pas la portée dont cet endpoint a besoin. | Non — le client doit faire émettre une clé avec cette portée. |
not-found | 404 | Aucune autorisation pour ce restaurant, ou pas de livraison ni d'enregistrement de ce nom. Les cas sont volontairement indiscernables. | Non. |
conflict | 409 | La requête entre en conflit avec une ressource existante. | Non. |
payload-too-large | 413 | Le corps de la requête dépasse la limite. | Non. |
rate-limit-exceeded | 429 | Votre client a dépassé son budget de requêtes. | Oui, après Retry-After. |
dependency-unavailable | 503 | Un composant dont l'API a besoin est brièvement indisponible. | Oui, avec temporisation. |
internal-error | 500 | Un échec inattendu, déjà consigné de notre côté. | Une fois, avec temporisation ; puis donnez-nous le requestId. |
Ce qu'un client devrait faire
Trois catégories, et rien d'autre ne mérite d'être codé :
Ne réessayez pas — 400, 401, 403, 404, 409, 413. La requête échouera de
nouveau à l'identique. Journalisez le type et le requestId, et faites-le
remonter : un 401 en particulier signifie qu'une personne, du côté de votre
client, a révoqué quelque chose, et une boucle de nouvelles tentatives ne fera
que le masquer pendant une semaine.
Réessayez avec temporisation — 429, 503. Respectez Retry-After sur un
429 ; c'est le nombre de secondes avant que votre budget ne se recharge, et ce
n'est pas une suggestion. Pour un 503, temporisation exponentielle avec gigue,
et renoncez plutôt que de marteler.
Réessayez une fois, puis escaladez — 500. Si cela se reproduit sur la même requête, ce n'est pas transitoire.
Tous les endpoints de cette API sont des GET, réessayer est donc toujours sans
danger du point de vue de l'API ; la raison de ne pas réessayer un 4xx est que
cela gaspille votre budget, pas que cela risque une double écriture.
Faire le lien avec vos propres journaux
Envoyez votre propre identifiant et il vous revient :
curl "https://api.backresto.com/v1/restaurants/$RESTAURANT_ID/deliveries?from=1787846400000&to=1787932800000" \
-H "Authorization: Bearer $BACKRESTO_PARTNER_API_KEY" \
-H "X-Request-ID: 3f7a1c9e-2b4d-4a86-9f0c-5e1d8b6a2c40" \
--include
La valeur est reprise dans l'en-tête de réponse et dans le requestId d'un
document problème, ce qui permet à un seul grep de répondre à « qu'a vu
BackResto quand mon job a échoué à 04:12 ? ».