Event Code Examples
Triggering Events via API
Frontend applications do not publish events directly. Instead, they perform actions via the REST API, which automatically publishes the corresponding domain events on the backend.
Example 1: Triggering "User Followed" Event
When you call the follow endpoint, the API publishes user.followed_user.
javascript
// Frontend Code
const handleFollowUser = async (followedUserId) => {
try {
// API call triggers the event on the backend
await fetch(`https://api.fundlyhub.org/api/v1/users/${followedUserId}/follow`, {
method: 'POST',
credentials: 'include'
});
toast.success('User followed successfully');
} catch (error) {
console.error('Failed to follow user:', error);
}
};Example 2: Triggering "Campaign Created" Event
Creating a campaign triggers campaign.created and starts the creation saga.
javascript
// Frontend Code
const handleCreateCampaign = async (campaignData) => {
try {
const response = await fetch('https://api.fundlyhub.org/api/v1/fundraisers', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include',
body: JSON.stringify(campaignData)
});
if (!response.ok) throw new Error('Creation failed');
// The backend has now published 'campaign.created'
const campaign = await response.json();
navigate(`/campaigns/${campaign.slug}`);
} catch (error) {
console.error('Failed to create campaign:', error);
}
};Backend Event Processing
Events are processed asynchronously by backend workers. Here is how a processor handles an event:
Example: Email Notification Processor
typescript
// Backend Code (Node.js Processor)
export class EmailNotificationProcessor {
constructor() {
EventBus.subscribe('user.followed_user', this.handle.bind(this));
}
async handle(event) {
const { followerId, followedUserId } = event.payload;
// Idempotency check
if (await this.isProcessed(event.id)) return;
try {
// Get user details
const user = await UserRepository.findById(followedUserId);
const follower = await UserRepository.findById(followerId);
// Send email
await EmailService.send({
to: user.email,
subject: 'You have a new follower!',
template: 'new_follower',
context: {
userName: user.name,
followerName: follower.name
}
});
console.log(`Email sent for event ${event.id}`);
await this.markProcessed(event.id);
} catch (error) {
console.error('Failed to process email notification:', error);
}
}
}Testing Events (Backend)
Integration tests verify that API calls trigger the correct events:
typescript
import { request } from 'supertest';
describe('Follow User Flow', () => {
it('should publish user.followed_user event', async () => {
// 1. Make API call
await request(app)
.post('/api/v1/users/user-123/follow')
.set('Cookie', `session=${sessionCookie}`)
.expect(200);
// 2. Verify event was published to store
const events = await EventStore.findEvents({
type: 'user.followed_user',
payload: { followedUserId: 'user-123' }
});
expect(events.length).toBe(1);
expect(events[0].payload.followerId).toBe(testUser.id);
});
});