Buenas Prácticas
Manejo de webhooks listo para producción: responde rápido, maneja duplicados, usa cola de procesamiento, manejo de errores y monitoreo.
Sigue estas prácticas para construir handlers de webhook confiables y listos para producción.
Responde Rápidamente
Devuelve un código de estado 2xx lo más rápido posible. GitScrum espera una respuesta dentro de 30 segundos. Si tu procesamiento tarda más, confirma la recepción inmediatamente y procesa de forma asíncrona.
Procesamiento Basado en Cola
Desacopla la recepción del procesamiento usando una cola de mensajes:
const Queue = require('bull');
const webhookQueue = new Queue('webhooks');
app.post('/webhooks/gitscrum', (req, res) => {
// Acknowledge immediately
res.status(200).json({ received: true });
// Queue for async processing
webhookQueue.add(req.body);
});
webhookQueue.process(async (job) => {
const event = job.data;
// Heavy processing here: database writes, API calls, notifications
await processWebhook(event);
});from celery import Celery
celery_app = Celery('webhooks', broker='redis://localhost:6379')
@app.route('/webhooks/gitscrum', methods=['POST'])
def webhook():
event = request.get_json()
# Acknowledge immediately
process_webhook.delay(event)
return jsonify({"received": True}), 200
@celery_app.task
def process_webhook(event):
# Heavy processing here
passManeja Duplicados
El mismo evento puede ser entregado más de una vez. Diseña tu handler para ser idempotente — procesar el mismo evento dos veces debe producir el mismo resultado.
Usa el UUID como Clave de Idempotencia
const processedEvents = new Set(); // Use Redis in production
webhookQueue.process(async (job) => {
const { data } = job.data;
const eventId = data.uuid;
// Skip if already processed
if (processedEvents.has(eventId)) {
console.log(`Skipping duplicate: ${eventId}`);
return;
}
processedEvents.add(eventId);
await processWebhook(job.data);
});Manejo de Errores
Captura Todas las Excepciones
Nunca dejes que tu handler de webhook falle. Envuelve el procesamiento en manejo de errores:
app.post('/webhooks/gitscrum', async (req, res) => {
try {
// Always respond 200 first
res.status(200).json({ received: true });
await processWebhook(req.body);
} catch (error) {
console.error('Webhook processing error:', error);
// Log the error but don't crash the server
}
});Registra Todo
Registra todos los webhooks recibidos para depuración y auditoría:
app.post('/webhooks/gitscrum', (req, res) => {
const timestamp = new Date().toISOString();
const headers = {
'x-header': req.headers['x-header'],
'user-agent': req.headers['user-agent'],
};
console.log(JSON.stringify({
timestamp,
headers,
body: req.body,
}));
res.status(200).json({ received: true });
});Monitoreo
Rastrea Tasas de Éxito de Entrega
Monitorea tu endpoint de webhook para:
- Tiempo de respuesta (mantén por debajo de 5 segundos)
- Tasas de error (respuestas 5xx)
- Tamaño del payload
- Profundidad de la cola de procesamiento
Endpoint de Health Check
Agrega un health check junto a tu endpoint de webhook:
app.get('/webhooks/health', (req, res) => {
res.status(200).json({
status: 'healthy',
queue_depth: webhookQueue.getJobCount(),
uptime: process.uptime(),
});
});Filtrado de Eventos
Si usas la misma URL de endpoint para múltiples eventos, filtra verificando la estructura del payload:
app.post('/webhooks/gitscrum', (req, res) => {
res.status(200).json({ received: true });
const { data } = req.body;
// Route based on payload structure
if (data.workflow) {
handleTaskEvent(data);
} else if (data.time_box) {
handleSprintEvent(data);
} else if (data.acceptance_criteria) {
handleUserStoryEvent(data);
}
});Separación de Ambientes
Usa endpoints de webhook diferentes para ambientes diferentes:
| Ambiente | Endpoint |
|---|---|
| Desarrollo | https://dev.your-server.com/webhooks/gitscrum |
| Staging | https://staging.your-server.com/webhooks/gitscrum |
| Producción | https://your-server.com/webhooks/gitscrum |
Configura proyectos GitScrum separados para cada ambiente y apunta los webhooks al endpoint correspondiente.
Pruebas con ngrok
Durante el desarrollo, usa una herramienta de tunelización como ngrok para exponer tu servidor local:
# Start your local server on port 3000
node server.js
# In another terminal, start ngrok
ngrok http 3000Copia la URL HTTPS de ngrok y pégala en la configuración de webhook de GitScrum. Esto permite probar webhooks contra tu servidor de desarrollo local.
Relacionado
- Inicio Rápido — Configura tu primer webhook
- Seguridad — Protege tus endpoints de webhook
- Solución de Problemas — Problemas comunes y soluciones