Cómo reintentar solicitudes cuando vuelves a estar en línea

Cuando realizas solicitudes a un servidor web, un error es una posibilidad. Es posible que el usuario haya perdido la conectividad o que el servidor remoto no funcione.

Si bien esta documentación se ha centrado principalmente en el manejo de solicitudes GET en un service worker, pueden entrar en juego otros métodos, como POST, PUT o DELETE. Estos métodos suelen usarse para comunicarse con APIs de backend y proporcionar datos para una app web. Cuando estas solicitudes fallan ante la ausencia de un service worker, el usuario debe reintentarlas de forma manual cuando está de nuevo en línea, y no es algo que los usuarios siempre recuerden hacer.

Si esto describe tu aplicación (y si hay un service worker en la mezcla), lo ideal sería que vuelvas a intentar enviar solicitudes con errores cuando el usuario vuelva a estar en línea. La API de BackgroundSync ofrece una solución a este problema. Cuando un service worker detecta una solicitud de red con errores, puede registrarse para recibir un evento sync si el navegador detecta que se devolvió la conectividad. El evento sync se puede entregar incluso si el usuario salió de la página que lo registró, lo que lo hace más eficaz que otros métodos para reintentar solicitudes con errores.

Workbox abstrae esta API con el módulo workbox-background-sync, lo que hace que la API de BackgroundSync sea más fácil de usar con otros módulos de Workbox. También implementa una estrategia de resguardo para los navegadores que aún no admiten BackgroundSync.

Uso básico

BackgroundSyncPlugin se exporta desde el módulo workbox-background-sync y se puede usar para poner en cola las solicitudes con errores y reintentarlas cuando se activen los eventos sync futuros:

import {BackgroundSyncPlugin} from 'workbox-background-sync';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

const bgSyncPlugin = new BackgroundSyncPlugin('myQueueName', {
  maxRetentionTime: 24 * 60 // Retry for max of 24 Hours (specified in minutes)
});

registerRoute(
  /\/api\/.*\/*.json/,
  new NetworkOnly({
    plugins: [bgSyncPlugin]
  }),
  // An optional third parameter specifies the request method
  'POST'
);

Aquí, BackgroundSyncPlugin se aplica a una ruta que coincide con solicitudes POST con una ruta de API que recupera datos JSON. Si el usuario no tiene conexión, BackgroundSyncPlugin volverá a intentar la solicitud cuando vuelva a estar en línea, pero solo durante un máximo de un día.

Uso avanzado

workbox-background-sync también proporciona una clase Queue, de la que puedes crear una instancia y agregarle solicitudes fallidas. Al igual que con BackgroundSyncPlugin, las solicitudes fallidas se almacenan en IndexedDB y se prueban cuando el navegador considera que se restableció la conectividad.

Crear una cola

Para crear una cola, crea una instancia de un objeto Queue con una cadena que represente el nombre de la cola:

import {Queue} from 'workbox-background-sync';

const queue = new Queue('myQueueName');

El nombre de la cola se usa como parte del nombre de la etiqueta que crea el método register() proporcionado por el SyncManager global. También es el nombre que se usa para el Almacén de objetos que proporciona la base de datos IndexedDB.

Agrega solicitudes a la cola

Después de crear la instancia Queue, puedes agregarle solicitudes con errores mediante el método pushRequest():

import {Queue} from 'workbox-background-sync';

const queue = new Queue('myQueueName');

self.addEventListener('fetch', (event) => {
  // Add in your own criteria here to return early if this
  // isn't a request that should use background sync.
  if (event.request.method !== 'POST') {
    return;
  }

  const bgSyncLogic = async () => {
    try {
      const response = await fetch(event.request.clone());
      return response;
    } catch (error) {
      await queue.pushRequest({request: event.request});
      return error;
    }
  };

  event.respondWith(bgSyncLogic());
});

Una vez agregadas a la cola, las solicitudes se reintentan automáticamente cuando el service worker recibe el evento sync, ya que el navegador considera que la red está disponible nuevamente. Los navegadores que no admiten la API de BackgroundSync volverán a intentar la solicitud cada vez que se inicie el service worker, lo que es una forma menos eficaz de reintentar una solicitud con errores, pero como resguardo.

Probando workbox-background-sync

Probar el comportamiento de la sincronización en segundo plano puede ser complicado, pero puedes hacerlo en Herramientas para desarrolladores de Chrome. El mejor enfoque actual es más o menos así:

  1. Carga una página que registre tu service worker.
  2. Desactiva la conexión de red de tu computadora o el servidor web. No uses el botón de activación sin conexión en las Herramientas para desarrolladores de Chrome La casilla de verificación sin conexión solo afecta a las solicitudes de la página, pero se seguirán procesando las solicitudes del service worker.
  3. Realiza solicitudes de red que deben estar en cola con workbox-background-sync. Para verificar las solicitudes que se colocaron en cola, consulta Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests.
  4. Ahora restablece la conectividad de red o vuelve a activar tu servidor web.
  5. Fuerza un evento sync anticipado en Chrome DevTools > Application > Service Workers. Ingresa el nombre de la etiqueta de workbox-background-sync:<your queue name>, en el que <your queue name> es el nombre de la cola que configuraste.
  6. Haz clic en el botón "Sincronizar" .
    Captura de pantalla de la utilidad de sincronización en segundo plano en el panel de la aplicación de Herramientas para desarrolladores de Chrome. Se especificó el evento de sincronización para una cola de &#39;myQueueName&#39;. de la columna “workbox-background-sync” módulo.
  7. Ahora deberías ver que se reintentaron las solicitudes de red que tenían errores y se procesaron. Como resultado, el almacén IndexedDB debería estar vacío, ya que las solicitudes se volvieron a reproducir con éxito.

Conclusión

Usar workbox-background-sync para reintentar las solicitudes de red fallidas puede ser una excelente manera de mejorar la experiencia del usuario y la confiabilidad de tu app, como permitir que los usuarios vuelvan a enviar solicitudes fallidas a la API para no perder los datos que querían enviar a tu API. También se puede usar para llenar vacíos en tus propios datos, como los análisis. De hecho, el módulo workbox-google-analytics usa workbox-background-sync de forma interna para reintentar las solicitudes fallidas para enviar datos a Google Analytics.

Sin importar cuál sea tu caso de uso, workbox-background-sync simplifica este tipo de tarea, lo que mejora tu experiencia de desarrollador y te brinda más oportunidades de mejorar la experiencia del usuario y la funcionalidad de tu aplicación web.