Tema representativo de entrevista

Entrevista general: ¿Cómo previene HTTP 428 Precondition Required las actualizaciones perdidas?

GeneralIntermedio
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Una API devuelve 428 para un PUT sin If-Match y 412 cuando el ETag está desactualizado. Explique la diferencia, el flujo del cliente y cómo el servidor evita las actualizaciones perdidas.

Prompt y contexto

Dos clientes editan el mismo documento. El servidor requiere actualizaciones condicionales: devuelve 428 cuando falta la condición y 412 cuando la condición suministrada ya no coincide. Explique cómo funcionan juntos ETag, If-Match, el almacenamiento en caché y los reintentos para que una escritura posterior no pueda sobrescribir silenciosamente una anterior.

Lo que evalúa el entrevistador

  • Distinguir 428 como un requisito de política de 412 como una condición evaluada fallida.
  • Usar un ETag fuerte e If-Match para el control de concurrencia optimista.
  • Diseñar los pasos de lectura, edición, envío, visualización de conflictos y fusión.
  • Manejar el almacenamiento en caché, la idempotencia, la auditabilidad y los límites de reintento.

Preguntas para aclarar antes de responder

  1. ¿Qué recursos y métodos de escritura requieren condiciones, y se permite If-Match: *?
  2. ¿El ETag es fuerte o débil, y cambia con cada actualización de representación protegida?
  3. ¿Cómo debe manejar el cliente 428, 412, 404 y 409 respectivamente?
  4. ¿Los conflictos se fusionan por campo, son elegidos por un usuario o se abandonan?
  5. ¿Cuáles son los requisitos de caché, versión, clave de idempotencia y auditoría?

Estructura de respuesta de 30 segundos

El cliente realiza un GET del recurso y guarda su ETag, luego envía la edición con If-Match. Una condición ausente recibe 428, indicándole al cliente que agregue una; una discrepancia recibe 412, indicándole que el recurso cambió. El cliente vuelve a leer, muestra la diferencia, fusiona y envía con el nuevo ETag en lugar de sobrescribir a ciegas. El servidor compara un ETag fuerte de forma atómica, registra versiones y datos de auditoría, y mantiene el almacenamiento en caché condicional separado de la protección de escritura.

Análisis detallado paso a paso

Paso 1: Separar 428 y 412

428 es una respuesta de política del servidor: la solicitud omitió una precondición requerida. 412 significa que se evaluó una condición suministrada y el estado actual del recurso no la satisfizo. Ninguna de las dos significa reintentar la solicitud original sin cambios.

Paso 2: Generar una versión del recurso

El servidor emite un ETag fuerte y lo cambia cada vez que cambia la representación protegida. El cliente almacena ese ETag de GET como su línea base de edición en lugar de confiar únicamente en una marca de tiempo local.

Paso 3: Enviar If-Match

El cliente envía If-Match con PUT, PATCH u otra actualización con efectos secundarios. Antes de aplicar la escritura, el servidor compara atómicamente el ETag actual; solo una coincidencia continúa, mientras que una discrepancia devuelve 412 y deja el recurso sin cambios.

http
GET /documents/42
ETag: "v17"

PUT /documents/42
If-Match: "v17"

Paso 4: Resolver el conflicto

Después de 412, realice un GET nuevamente y muestre la versión del servidor junto a los cambios locales. Fusione campos cuando la política lo permita; de lo contrario, pida al usuario que elija. Nunca reenvíe el valor de If-Match desactualizado.

Paso 5: Diseñar el comportamiento de la caché

Un GET condicional puede usar If-None-Match y recibir 304, mientras que la protección de escritura usa If-Match. Las cachés no deben tratar un ETag antiguo como actual ni almacenar en caché un error de forma que revele el estado del recurso.

Paso 6: Manejar fallos y reintentos

Después de un tiempo de espera de red, no reproduzca a ciegas una escritura no idempotente. Consulte la versión del recurso o utilice una clave de idempotencia para establecer el resultado. Un 428 necesita una precondición; un 412 necesita una relectura y fusión.

Paso 7: Registrar y verificar

Rastree versiones, ETags, recuentos de conflictos, tasa de fusión automática y abandono de usuarios. Una prueba de actualización concurrente debería mostrar a un escritor teniendo éxito y al otro recibiendo 412, con un registro de auditoría para cada cambio de versión.

Respuesta de muestra de alta calidad

Devolvería un ETag fuerte como "v17" desde GET y haría que el cliente lo conserve durante la edición. Un PUT sin If-Match devuelve 428 con una instrucción para usar una actualización condicional; un ETag desactualizado falla la comparación atómica y devuelve 412. Luego, el cliente obtiene la última versión mediante GET, muestra las diferencias, fusiona y reintenta con el nuevo ETag en lugar de reproducir la condición desactualizada. If-None-Match y 304 optimizan las lecturas pero no protegen las escrituras. Una escritura con tiempo de espera agotado se verifica por versión o clave de idempotencia antes de cualquier reintento, y monitoreamos las tasas de conflicto y fusión.

Errores comunes

  • Tratar tanto 428 como 412 como errores transitorios y reintentar indefinidamente.
  • Reemplazar la comparación de ETag fuerte con una marca de tiempo del cliente.
  • Sobrescribir la versión del servidor después de recibir 412.
  • Confundir la validación de caché de If-None-Match con la protección de escritura de If-Match.
  • Reproducir incondicionalmente una escritura con efectos secundarios después de un tiempo de espera.

Preguntas de seguimiento y respuestas

Pregunta de seguimiento 1: ¿Por qué no usar Last-Modified?

La precisión de la marca de tiempo y los problemas de reloj pueden hacer que dos versiones parezcan iguales. Un ETag fuerte se vincula directamente a la versión de la representación y es mejor para prevenir actualizaciones perdidas.

Pregunta de seguimiento 2: ¿Cuándo es útil If-Match: *?

Expresa que el recurso debe existir o evita la creación o el reemplazo contra una versión desconocida, según el contrato de la API. No es una escritura incondicional.

Pregunta de seguimiento 3: ¿En qué se diferencia 412 de 409?

412 significa que no se cumplió una precondición HTTP. 409 significa que la solicitud entra en conflicto con el estado actual del recurso a nivel de negocio. Una API puede usar ambos, pero debe indicar la acción de recuperación.

Pregunta de seguimiento 4: ¿Cómo fusionaría a nivel de campo?

Cargue la línea base común, la versión del servidor y la versión local, luego fusione según la política de campos. Envíe los conflictos del mismo campo al usuario y envíe el resultado con un nuevo ETag.

Pregunta de seguimiento 5: ¿Qué pasa si una caché devuelve un ETag antiguo?

Utilice un control de caché adecuado o una revalidación antes de editar y fuerce una lectura de origen después de una actualización fallida. La comparación atómica del servidor con la versión actual sigue siendo autoritativa.

Pregunta de seguimiento 6: ¿Cómo prueba la seguridad de concurrencia?

Haga que dos clientes lean un ETag y escriban simultáneamente. Verifique que exactamente uno tenga éxito y el otro reciba 412, luego cubra reintentos, tiempos de espera, cachés y la ruta de auditoría.

Fuentes públicas

Preguntas relacionadas