How to Implement Event-Driven Architecture in Go

Web
Use Go channels and a central event bus to decouple components and handle asynchronous events efficiently.

Implement event-driven architecture in Go by using channels to decouple producers and consumers, allowing goroutines to communicate asynchronously. Create a central event bus that broadcasts events to multiple subscribers, ensuring loose coupling between components.

package main

import (
	"fmt"
	"sync"
)

type Event struct {
	Type string
	Data interface{}
}

type EventBus struct {
	subscribers map[string][]chan Event
	mu          sync.RWMutex
}

func NewEventBus() *EventBus {
	return &EventBus{subscribers: make(map[string][]chan Event)}
}

func (bus *EventBus) Subscribe(eventType string, ch chan Event) {
	bus.mu.Lock()
	defer bus.mu.Unlock()
	bus.subscribers[eventType] = append(bus.subscribers[eventType], ch)
}

func (bus *EventBus) Publish(event Event) {
	bus.mu.RLock()
	defer bus.mu.RUnlock()
	for _, ch := range bus.subscribers[event.Type] {
		ch <- event
	}
}

func main() {
	bus := NewEventBus()
	eventChan := make(chan Event, 10)
	bus.Subscribe("order.created", eventChan)

	go func() {
		for e := range eventChan {
			fmt.Printf("Received: %v - %v\n", e.Type, e.Data)
		}
	}()

	bus.Publish(Event{Type: "order.created", Data: "Order #123"})
}