Todos los artículos
Eventos de inserción, actualización y eliminación de filas de Postgres que fluyen desde una base Supabase hasta un endpoint webhook local seguro.
Supabasedatabase webhooksPostgreslocal development

Probar Supabase Database Webhooks en localhost

Para probar un Supabase Database Webhook en localhost, utilice host.docker.internal cuando Supabase y su receptor se ejecutan en su máquina, o utilizar un túnel HTTPS público cuando un proyecto hospedado Supabase debe llamar a su aplicación local. La distinción importa: Postgres local se ejecuta en Docker, donde localhost significa el contenedor de bases de datos, mientras hospedado Supabase necesita una URL accesible a Internet.

Qué Supabase Database Webhooks enviar

Database Webhooks reacciona a Postgres INSERT, UPDATE, y DELETE operaciones en una tabla seleccionada. Supabase los describe como un envoltorio asincrónico alrededor de los desencadenantes usando el pg_net extensión. La transacción que cambia la fila no espera que su receptor termine su lógica de negocio, lo que reduce el acoplamiento, pero también significa que el receptor debe ser observable y desconocido.

La carga útil JSON identifica la operación, esquema y tabla e incluye datos de fila. Para insertar y actualizar, record contiene la nueva fila. Para actualizaciones y eliminaciones, old_record proporciona la fila anterior donde está disponible. Construir controladores alrededor del sobre documentado en lugar de tratar cada solicitud como sólo un objeto de fila.

Montaje local versus proyecto alojado

Supabase local a una aplicación local: utilice el host Docker

Cuando corres supabase start, Postgres está dentro de un contenedor. Una URL de Webhook como http://localhost:3000/api/supabase-db-hook los bucles de vuelta en ese contenedor y generalmente falla. Supabase oficial Database Webhooks documentación dice que el objetivo host.docker.internal:

http://host.docker.internal:3000/api/supabase-db-hook

Esta ruta no requiere un túnel público. En los motores Linux donde ese nombre de host no está disponible, utilice el mapeo de host-gateway soportado por su configuración Docker o la dirección LAN de su máquina, como sugieren los puntos Supabase. Confirme desde un contenedor, no sólo desde el navegador host.

Hosted Supabase a una aplicación local: use HTTPS

Una base de datos en la nube no puede resolver el nombre de host Docker de su computadora portátil o dirección de vuelta privada. Iniciar la aplicación local y ejecutar npx portpreview 3000, luego configure:

https://your-subdomain.portpreview.dev/api/supabase-db-hook

Utilice un proyecto de desarrollo dedicado o una tabla de bajo riesgo. Un webhook de nube puede incluir datos de fila real, por lo que exponer una tabla de producción a una URL de desarrollo temporal es generalmente una estrategia de prueba deficiente.

Crear un receptor que valide un secreto compartido

A diferencia de los proveedores que definen un encabezado HMAC obligatorio, un Database Webhook es una solicitud HTTP configurable. Protege el endpoint con un encabezado secreto que controlas y configuras el mismo encabezado en el webhook. TLS lo protege en tránsito; una comparación de tiempo constante evita filtrar el tiempo de prefijo secreto a través de su aplicación.

// app/api/supabase-db-hook/route.ts
import crypto from 'node:crypto';

function safeEqual(a: string, b: string) {
  const left = Buffer.from(a);
  const right = Buffer.from(b);
  return left.length === right.length &&
    crypto.timingSafeEqual(left, right);
}

export async function POST(request: Request) {
  const supplied = request.headers.get('x-webhook-secret') ?? '';
  const expected = process.env.SUPABASE_DB_WEBHOOK_SECRET ?? '';

  if (!expected || !safeEqual(supplied, expected)) {
    return new Response('unauthorized', { status: 401 });
  }

  const payload = await request.json();
  if (!['INSERT', 'UPDATE', 'DELETE'].includes(payload.type)) {
    return new Response('unsupported event', { status: 400 });
  }

  await recordDelivery(payload);
  return new Response('accepted', { status: 200 });
}

Un encabezado compartido demuestra conocimiento del secreto pero no une criptográficamente ese secreto al cuerpo. Si se requiere evidencia de amortiguación a nivel de cuerpo, envíe el Database Webhook a un pequeño Edge Function de confianza que valida su propio secreto inbound, computa su HMAC elegido sobre un cuerpo canónico y lo envía al consumidor local o de producción. No inventes un X-Supabase-Signature suposición a menos que su propia capa de reenvío crea y lo verifica.

Configurar y activar un Webhook enfocado

  1. Elija una tabla de desarrollo y decida qué operaciones importan.
  2. Cree el Database Webhook en el panel Supabase bajo la base de datos → Webhooks, seleccionando el esquema, tabla y operaciones.
  3. Establecer la URL local Docker o la URL del túnel público descrita anteriormente.
  4. Añadir Content-Type: application/json y un azar X-Webhook-Secret valor donde está disponible la configuración de encabezados webhook.
  5. Comience el receptor e inserte una fila de prueba claramente etiquetada.
  6. Actualizar un campo, luego eliminar la fila, verificar todos los sobres seleccionados.
  7. Eliminar o desactivar el webhook de prueba antes de cambiar proyectos o cerrar el túnel.

Nombre de las filas de prueba para limpiar es determinista. No dispare una integración en toda la mesa en los registros de los clientes de producción simplemente para ver una solicitud llegar.

Interpretar INSERT, UPDATE y DELETE de forma segura

INSERT

Uso record como el estado recién insertado. Si el receptor crea un objeto correspondiente en otro lugar, almacena la clave principal de la tabla fuente como clave de idempotencia. Un evento de inserción se puede enviar de nuevo durante la repetición manual o el procesamiento de reingreso personalizado.

UPDATE

Compare record con old_record y actuar sólo en campos relevantes para la integración. Un webhook de actualización general puede disparar para los timetamps o metadatos no relacionados. Filtrar cambios de negocio no-op evita costosas llamadas de abajo.

DELETE

La fila eliminada está representada por datos anteriores en lugar de un registro actual. Hacer manipuladores de eliminación tolerantes a campos opcionales desaparecidos y decidir si la acción aguas abajo es la eliminación, archivo o revocación. Requisitos de auditoría de presto.

switch (payload.type) {
  case 'INSERT':
    await mirror.upsert(payload.record.id, payload.record);
    break;
  case 'UPDATE':
    if (payload.old_record.status !== payload.record.status) {
      await syncStatus(payload.record.id, payload.record.status);
    }
    break;
  case 'DELETE':
    await mirror.archive(payload.old_record.id);
    break;
}

Confiabilidad de entrega es una preocupación de aplicación

Debido a que Database Webhooks son solicitudes de red asincrónicas, no trate la recepción como una transacción distribuida con el cambio de fila originario. Su lado remoto puede no estar disponible después de que Postgres se comprometa. Supervisar los resultados de solicitud y diseñar la reconciliación para cualquier cosa que no pueda perderse.

Para los flujos de trabajo de alto valor, una tabla de outbox es más fuerte: escribir un cambio de negocio y una fila de outbox en una transacción de base de datos, luego dejar a un trabajador entregar con contadores de reingreso explícitos, retroceso y manejo de letras muertas. Un Database Webhook puede notificar al trabajador, pero la reconciliación periódica todavía debe encontrar filas de outbox sin entrega.

Haga el receptor idempotent. Una clave útil combina esquema de fuente, tabla, operación, clave primaria y una versión de fila estable como updated_at; para garantías estrictas, agregue un evento inmutable UUID en una fila outbox. Evite escalar sólo la fila actual porque dos transiciones válidas pueden producir proyecciones similares.

Llamando a un Supabase local

Si el destino es un Edge Function servido por la pila Supabase local, el ejemplo documentado es:

http://host.docker.internal:54321/functions/v1/my-function-name

El funcionario Edge Functions guía de desarrollo usos supabase functions serve [function-name] para recargar caliente local. Edge Functions requiere verificación JWT por defecto. Para una función webhook que no puede suministrar un usuario JWT, configure esa función deliberadamente, por ejemplo con verify_jwt = false dentro supabase/config.toml, como se documenta en Configuración de funciones. Reemplazar la autenticación JWT con su cabeza secreta o cheque de firma; desactivar JWT solo hace la función pública.

Solución de problemas Supabase webhook localhost delivery

Conexión rechazada de la pila local

Reemplazamiento localhost con host.docker.internal, verificar la aplicación se une a una interfaz accesible desde Docker, y confirmar el puerto. En Linux, configura la resolución host-gateway o utiliza la IP host. Un servicio vinculado sólo a una interfaz inesperada puede rechazar el tráfico de contenedores.

El proyecto hospedado nunca llega a la ruta

Un proyecto hospedado necesita la URL del túnel público HTTPS, no el nombre de host Docker. Confirme que el túnel está en vivo y su URL incluye la ruta completa. Chequee DNS/TLS poniéndolo usted mismo.

La ruta regresa 401

Compare el nombre y el valor del encabezado configurados, observe el espacio blanco líder o rastreador, y reinicie la aplicación después de cambiar variables de entorno. Inicie si el encabezado existe, nunca su valor. Si un intermediario tira los encabezados personalizados, utilice un Authorization: Bearer ... encabezado y validarlo explícitamente.

La forma de la carga parece equivocada

Lograr sólo las claves de primer nivel, operación, esquema y mesa en desarrollo. Recuerde que DELETE utiliza datos de fila anteriores y UPDATE puede incluir ambas versiones. Validar contra los ejemplos oficiales de carga útil actuales antes de cambiar su parser.

La actualización de la base de datos tiene éxito pero falta trabajo corriente

Ese comportamiento es posible en un diseño asincrónico. Inspeccione los registros de solicitud webhook pg_net Diagnóstico disponible en su entorno, luego añadir reingreso o reconciliación en lugar de revertir una transacción comercial ya comprometida.

Lista de verificación de seguridad

  • Utilice HTTPS para las pruebas alocal y rotar el secreto compartido temporal después.
  • Envíe únicamente las columnas necesarias; evite exponer tablas sensibles o grandes cargas de producción.
  • Validar un encabezado secreto antes de analizar o persistir el cuerpo.
  • Aplicar POST solo enrutamiento, límites de tamaño de solicitud, controles de velocidad y registros redactados.
  • Utilice configuraciones separadas local, estadificación y webhook de producción.
  • Construir registros explícitos, idempotencia, monitoreo y reconciliación para eventos importantes.
  • Desactivar URLs temporales de nube webhook cuando el túnel se cierra.

El fallo local más común es la dirección de red, no Postgres: llamadas locales-container utilizan host.docker.internal; las llamadas nubes usan un túnel público. Una vez que llegue el tráfico, trate la autenticación y las garantías de entrega como problemas de diseño separados. Examen seguridad del túnel local y patrones de confiabilidad webhook antes de conectar datos sensibles.

Preguntas frecuentes

¿Por qué un Supabase Database Webhook no alcanza localhost?
Supabase Postgres se ejecuta en Docker, por lo que localhost se refiere al contenedor. Utilice host.docker.internal o su IP host. Un proyecto hospedado Supabase necesita en cambio una URL de túnel HTTPS pública.
¿Necesito un túnel para Supabase Database Webhooks local?
No cuando tanto Supabase como el receptor son locales; use Docker host routing. Necesitas un túnel cuando un proyecto Supabase hospedado debe llamar a una aplicación que se ejecuta en tu computadora.
¿Se firma Supabase Database Webhooks automáticamente?
No asuma un encabezado HMAC proveedor. Configurar y validar un encabezado secreto compartido. Si necesita una firma llena de cuerpo, adelante a través de una función de confianza que crea un HMAC su receptor verifica.
¿Qué datos envía un Supabase Database Webhook?
El sobre JSON identifica INSERT, UPDATE, o DELETE más el esquema y la tabla. Incluye el nuevo registro de insertos y actualizaciones y datos anteriores de fila para actualizaciones o eliminaciones cuando esté disponible.