Kullanıcı bir rapor (ör. Excel export) istediğinde işlem dakikalar sürüyorsa bunu uçtan uca nasıl tasarlarsınız?

Cevap

Uzun süren işlemler HTTP isteği içinde senkron yapılmaz; aksi halde istek timeout olur (load balancer genelde 30-60 sn'de keser) ve sunucu kaynakları kilitlenir. Doğru yaklaşım asenkron job: istek bir iş oluşturur, bir worker arka planda işler, client sonucu sonradan alır.

Akış

  1. Client POST /api/exports gönderir.
  2. Backend bir jobs kaydı oluşturur (status: pending), işi kuyruğa (BullMQ, SQS, RabbitMQ) atar ve hemen `202 Accepted` ile jobId döner.
  3. Worker işi alır, ilerlemeyi günceller (progress: 40), dosyayı S3'e yükler, status: done ve dosya anahtarını kaydeder.
  4. Client durumu öğrenir: polling (GET /api/exports/:id her 2-3 sn), SSE/WebSocket ile push veya iş bitince e-posta/bildirim.
  5. Dosya kısa ömürlü bir presigned URL ile indirilir.
// API
app.post("/api/exports", requireAuth, async (req, res) => {
  const job = await db.job.create({ data: { userId: req.user.id, type: "orders-xlsx", status: "pending" } });
  await exportQueue.add("orders-xlsx", { jobId: job.id, filters: req.body });
  res.status(202).location(`/api/exports/${job.id}`).json({ jobId: job.id });
});

// Worker
new Worker("exports", async (j) => {
  const file = await buildXlsx(j.data.filters, (p) => db.job.update({ where: { id: j.data.jobId }, data: { progress: p } }));
  const key = await s3Upload(file);
  await db.job.update({ where: { id: j.data.jobId }, data: { status: "done", fileKey: key } });
});

Dikkat edilecekler

  • Retry ve idempotency: worker çökerse iş tekrar çalışabilir; aynı işin iki kez yapılması zarar vermemeli.
  • Kullanıcı aynı butona 5 kez basarsa: aynı filtrelerle bekleyen bir job varsa yenisini oluşturmayın.
  • Büyük veri: veriyi tek seferde belleğe almak yerine stream/cursor ile okuyup dosyaya akıtın.
  • Yetki: GET /api/exports/:id sadece job sahibine açık olmalı.
  • Temizlik: eski dosyalar S3 lifecycle kuralı ile silinmeli.
  • UI'da ilerleme çubuğu, sayfadan çıkılsa bile işin devam ettiğini belirten bir mesaj ve "dışa aktarımlarım" listesi deneyimi iyileştirir.
  1. SSR, SSG ve CSR arasındaki farklar nelerdir?OrtaWeb MimarisiFull Stack
  2. Monorepo nedir? Avantajları, dezavantajları ve araçları nelerdir?ZorWeb MimarisiFull Stack
  3. MVC mimarisi nedir? Modern web uygulamalarında nasıl karşılık bulur?KolayWeb MimarisiFull Stack
  4. Bir kullanıcı girişinin uçtan uca akışını (frontend'den veritabanına) anlatın.OrtaWeb MimarisiFull Stack
  5. Büyük dosya yükleme akışını nasıl tasarlarsınız? Presigned URL nedir?ZorWeb MimarisiFull Stack
  6. Backend for Frontend (BFF) deseni nedir, ne zaman kullanılır?OrtaWeb MimarisiFull Stack

Bu konuda başka bir soru biliyor musun?

Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.

Soru ekle