< cd ../
NestJS NestJS Event-Driven Architecture Webhook Backend Development Microservices

Membangun Sistem Reaktif dengan Event-Driven Architecture dan Webhook Fan-out di NestJS

Pelajari cara mengimplementasikan event-driven architecture menggunakan pola webhook fan-out di NestJS untuk membangun aplikasi yang skalabel dan responsif.

AUTHOR: code.santuy DATE: 2026-06-25 READ: 5m
Membangun Sistem Reaktif dengan Event-Driven Architecture dan Webhook Fan-out di NestJS

Memahami Event-Driven Architecture (EDA)

Dalam dunia pengembangan perangkat lunak modern, membangun aplikasi yang responsif, skalabel, dan tangguh menjadi semakin penting. Salah satu pendekatan arsitektur yang sangat efektif untuk mencapai tujuan ini adalah Event-Driven Architecture (EDA). EDA adalah pola desain di mana perubahan status atau kejadian dalam suatu sistem (disebut 'event') memicu tindakan atau komunikasi antar komponen sistem.

Bayangkan sebuah toko online. Ketika pesanan baru dibuat, ini adalah sebuah 'event'. Event ini kemudian dapat memicu berbagai tindakan lain secara otomatis: mengirim email konfirmasi ke pelanggan, memperbarui stok barang, memulai proses pengiriman, dan mungkin memberi tahu tim pemasaran tentang penjualan baru.

Keuntungan utama dari EDA meliputi:

  • Decoupling (Pemisahan): Komponen-komponen sistem tidak perlu saling mengetahui secara langsung. Mereka hanya perlu tahu cara bereaksi terhadap event tertentu.
  • Scalability (Skalabilitas): Anda dapat dengan mudah menambahkan atau menghapus komponen yang bereaksi terhadap event tanpa memengaruhi komponen lain.
  • Resilience (Ketahanan): Jika satu komponen gagal, komponen lain yang tidak bergantung padanya dapat terus berfungsi.
  • Real-time Processing (Pemrosesan Real-time): EDA sangat cocok untuk aplikasi yang membutuhkan pembaruan dan respons instan.

Mengenal Webhook

Webhook adalah mekanisme yang memungkinkan aplikasi untuk mengirimkan data secara otomatis ke aplikasi lain ketika suatu event terjadi. Ini sering disebut sebagai 'reverse API' atau 'API yang didorong oleh event'. Alih-alih aplikasi Anda secara aktif meminta data (polling), aplikasi lain akan 'memberi tahu' Anda ketika ada sesuatu yang baru.

Secara teknis, webhook biasanya bekerja melalui HTTP POST request. Ketika sebuah event terjadi di sistem sumber, sistem tersebut akan mengirimkan data (payload) event tersebut ke URL endpoint yang telah ditentukan di sistem target. Sistem target kemudian dapat memproses data tersebut sesuai kebutuhan.

Contoh umum penggunaan webhook:

  • Integrasi dengan layanan pihak ketiga seperti GitHub (memberi tahu tentang commit baru), Stripe (memberi tahu tentang pembayaran berhasil), atau Slack (mengirim notifikasi).
  • Komunikasi antar layanan mikro dalam sebuah arsitektur terdistribusi.

Pola Fan-out: Mengirim Event ke Banyak Penerima

Dalam konteks EDA, 'fan-out' merujuk pada pola di mana satu event yang dipublikasikan perlu dikirimkan ke banyak konsumen atau penerima yang berbeda. Bayangkan sebuah pengumuman penting yang perlu didengar oleh banyak orang sekaligus. Pola fan-out memastikan bahwa setiap penerima menerima informasi yang sama.

Dalam implementasi webhook, pola fan-out berarti ketika sebuah event terjadi di sistem Anda, Anda akan mengirimkan notifikasi webhook ke beberapa URL endpoint yang berbeda. Setiap endpoint ini mewakili layanan atau komponen yang perlu bereaksi terhadap event tersebut.

Misalnya, ketika pengguna baru mendaftar di aplikasi Anda:

  1. Event USER_REGISTERED dipublikasikan.
  2. Sistem Anda perlu memberi tahu:
    • Layanan autentikasi untuk membuat kredensial.
    • Layanan notifikasi untuk mengirim email selamat datang.
    • Layanan analitik untuk mencatat pendaftaran baru.
    • Layanan CRM untuk memperbarui data pelanggan.

Dengan pola fan-out, satu event USER_REGISTERED akan memicu pengiriman webhook ke URL endpoint masing-masing layanan tersebut.

Implementasi Webhook Fan-out di NestJS

NestJS adalah framework Node.js yang progresif dan berorientasi pada kelas untuk membangun aplikasi sisi server yang efisien dan skalabel. Dengan fitur-fitur bawaannya dan ekosistem modul yang kaya, NestJS sangat cocok untuk mengimplementasikan pola EDA, termasuk webhook fan-out.

Mari kita lihat contoh sederhana bagaimana kita bisa mengimplementasikannya:

1. Mendefinisikan Event dan Payload

Pertama, kita perlu mendefinisikan struktur data (payload) untuk event kita. Misalnya, untuk event ORDER_CREATED:

interface OrderCreatedPayload {
  orderId: string;
  userId: string;
  amount: number;
  timestamp: Date;
}

2. Service untuk Mengirim Webhook

Kita akan membuat sebuah service yang bertanggung jawab untuk mengirimkan webhook. Service ini akan menerima payload event dan daftar URL endpoint penerima.

// webhook.service.ts
import { Injectable, Logger } from '@nestjs/common';
import axios from 'axios';

@Injectable()
export class WebhookService {
  private readonly logger = new Logger(WebhookService.name);
  private readonly webhookUrls: string[] = [
    'https://service-a.example.com/webhook',
    'https://service-b.example.com/webhook',
    'https://service-c.example.com/webhook',
    // Tambahkan URL lain sesuai kebutuhan
  ];

  async sendWebhook<T>(event: string, payload: T): Promise<void> {
    const dataToSend = {
      event,
      payload,
    };

    for (const url of this.webhookUrls) {
      try {
        this.logger.log(`Sending webhook for event '${event}' to ${url}`);
        await axios.post(url, dataToSend, {
          headers: {
            'Content-Type': 'application/json',
            // Anda mungkin ingin menambahkan header otentikasi di sini
          },
          timeout: 5000, // Timeout untuk mencegah request menggantung terlalu lama
        });
        this.logger.log(`Successfully sent webhook to ${url}`);
      } catch (error) {
        this.logger.error(`Failed to send webhook to ${url}: ${error.message}`);
        // Pertimbangkan strategi retry atau logging yang lebih canggih di sini
      }
    }
  }
}

3. Mempublikasikan Event

Dalam modul atau controller yang relevan (misalnya, OrdersModule), ketika sebuah event penting terjadi, kita akan memanggil WebhookService.

// orders.service.ts
import { Injectable } from '@nestjs/common';
import { WebhookService } from '../webhook/webhook.service';

interface Order {
  id: string;
  userId: string;
  totalAmount: number;
}

@Injectable()
export class OrdersService {
  constructor(private readonly webhookService: WebhookService) {}

  async createOrder(orderData: any): Promise<Order> {
    // Logika untuk membuat order di database...
    const createdOrder: Order = { ...orderData, id: 'order-123' }; // Simulasi order dibuat

    // Setelah order berhasil dibuat, publikasikan event
    await this.webhookService.sendWebhook('ORDER_CREATED', {
      orderId: createdOrder.id,
      userId: createdOrder.userId,
      amount: createdOrder.totalAmount,
      timestamp: new Date(),
    });

    return createdOrder;
  }
}

4. Konfigurasi di AppModule

Pastikan WebhookService di-provide di AppModule atau modul yang relevan.

// app.module.ts
import { Module } from '@nestjs/common';
import { OrdersModule } from './orders/orders.module';
import { WebhookModule } from './webhook/webhook.module';

@Module({
  imports: [OrdersModule, WebhookModule],
})
export class AppModule {}
// webhook.module.ts
import { Module } from '@nestjs/common';
import { WebhookService } from './webhook.service';

@Module({
  providers: [WebhookService],
  exports: [WebhookService], // Ekspor agar bisa di-inject di modul lain
})
export class WebhookModule {}

Pertimbangan Penting

  • Keamanan: Selalu validasi webhook yang masuk di sisi penerima. Gunakan signature atau secret key untuk memverifikasi bahwa request benar-benar berasal dari sistem Anda.
  • Ketahanan (Reliability): Apa yang terjadi jika salah satu endpoint penerima tidak tersedia? Implementasikan strategi retry (dengan backoff eksponensial) atau gunakan message queue (seperti RabbitMQ, Kafka, atau Redis Streams) sebagai perantara untuk memastikan event tidak hilang.
  • Monitoring: Pantau tingkat keberhasilan pengiriman webhook. Log error dengan detail yang memadai.
  • Idempotensi: Pastikan layanan penerima dapat menangani event yang diterima berulang kali (idempotent) jika terjadi retry atau duplikasi.
  • Konfigurasi: URL endpoint penerima sebaiknya dikonfigurasi melalui variabel lingkungan atau file konfigurasi, bukan di-hardcode.

Kesimpulan

Event-Driven Architecture dengan pola webhook fan-out adalah cara yang ampuh untuk membangun sistem yang terdistribusi, skalabel, dan responsif. NestJS menyediakan fondasi yang kuat untuk mengimplementasikan pola ini dengan mudah berkat struktur modularnya dan dukungan untuk dependency injection. Dengan perencanaan yang matang terkait keamanan, ketahanan, dan monitoring, Anda dapat membangun aplikasi yang tangguh dan siap menghadapi pertumbuhan di masa depan.

// related posts

~ $ e.hary_

© 2026 Eko Haryono > @code.santuy

GitHub TikTok Instagram