Errores
Un documento de problema legible por máquina para cada fallo, y qué significa cada tipo para su lógica de reintentos.
Todo fallo —incluida una ruta que no existe— responde con
application/problem+json, la forma definida por el RFC 9457. No hay ninguna vía
en esta API que devuelva una página de error HTML, así que un analizador que
asuma JSON en una respuesta no 2xx es seguro.
{
"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 es el identificador estable: ramifique sobre él, no sobre detail, que es
prosa y puede reformularse. requestId es el valor que conviene citar en un
mensaje a soporte: también se devuelve en la cabecera de respuesta
X-Request-ID, y usted puede establecer esa cabecera para correlacionarla con
sus propias trazas.
El catálogo
Sufijo de type | Estado | Qué ha pasado | ¿Reintentar? |
|---|---|---|---|
invalid-request | 400 | Falta un parámetro o está malformado: un rango de entregas invertido o demasiado largo, una colección desconocida, o un cursor que no coincide con el restaurante, la colección y el limit con los que pagina. | No — corrija la petición. |
unauthorized | 401 | Sin cabecera Authorization, o una clave malformada, desconocida, revocada, caducada o que se ha quedado sin ninguna concesión. | No — la clave necesita atención. |
forbidden | 403 | La clave tiene una concesión para este restaurante pero no el permiso que este endpoint necesita. | No — el cliente debe pedir una clave con ese permiso. |
not-found | 404 | Sin concesión para este restaurante, o esa entrega o ese registro no existe. Los casos son deliberadamente indistinguibles. | No. |
conflict | 409 | La petición entra en conflicto con un recurso existente. | No. |
payload-too-large | 413 | El cuerpo de la petición supera el límite. | No. |
rate-limit-exceeded | 429 | Su cliente ha superado su presupuesto de peticiones. | Sí, después de Retry-After. |
dependency-unavailable | 503 | Un componente que la API necesita no está disponible momentáneamente. | Sí, con backoff. |
internal-error | 500 | Un fallo inesperado, ya registrado por nuestra parte. | Una vez, con backoff; después indíquenos el requestId. |
Qué debería hacer un cliente
Tres grupos, y nada más merece el código:
No reintentar — 400, 401, 403, 404, 409, 413. La petición volverá a fallar de
forma idéntica. Registre el type y el requestId, y hágalo visible: un 401 en
particular significa que una persona del lado de su cliente ha revocado algo, y un
bucle de reintentos solo lo ocultará durante una semana.
Reintentar con backoff — 429, 503. Respete Retry-After en un 429; es el
número de segundos hasta que se recarga su presupuesto, y no es una sugerencia.
Para un 503, backoff exponencial con jitter, y ríndase en lugar de machacar el
servicio.
Reintentar una vez y luego escalar — 500. Si se repite en la misma petición, no es transitorio.
Todos los endpoints de esta API son GET, así que reintentar siempre es seguro
desde el punto de vista de la API; la razón para no reintentar un 4xx es que
malgasta su presupuesto, no que arriesgue una doble escritura.
Correlacionar con sus propios logs
Envíe su propio identificador y le vuelve:
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
El valor se refleja en la cabecera de respuesta y en el requestId de un
documento de problema, lo que hace que un solo grep responda a «¿qué vio
BackResto cuando mi tarea falló a las 04:12?».