Messaging & Events
Services communicate asynchronously through RabbitMQ using exactly two exchanges. Anything beyond these two patterns needs an architecture decision first.
os.rpc — synchronous request-reply (direct exchange)
Used for one approved path only: the tickets service enriching tickets with organizational data owned by the auth service.
Routing keys: auth.department.get-by-id, auth.project.get-by-id, auth.pmo.get. The auth/user service remains the source of truth — RPC never transfers data ownership.
os.events — fire-and-forget domain events (durable topic exchange)
The tickets service publishes events with routing key ticket.<eventtype>; the integration service consumes them via queue integration.notifications (bound to ticket.*, with a dead-letter queue) and turns them into in-app notifications.
Pinned event types: ASSIGNED, PARTICIPANT_ADDED, COMMENT_ADDED, INTERNAL_NOTE_ADDED, CLOSED_NEEDS_RESPONSE, SLA_BREACHED, RELATIVE_CREATED.
Envelope: includes eventId (for consumer idempotency), recipientUserIds, occurredAt, and an event-specific data payload. The contract is duplicated deliberately on both sides (os-tickets-service/src/events/ticket-event.types.ts and os-integration-service/src/notifications/notification-event.types.ts) — if you change one, change the other.
Rules of the road
- No Kafka, no service discovery (Eureka) — RabbitMQ and static Traefik routing only.
- Publishing is fire-and-forget; never block a request on event delivery.
- Consumers must tolerate duplicates (use
eventId) and route poison messages to the DLQ. - New RPC paths require explicit approval in the design docs; default to synchronous HTTP through the gateway.
Where to look in code
| What | Where |
|---|---|
| Tickets RPC clients | os-tickets-service/src/messaging/*-lookup-client.service.ts |
| Auth RPC responders | os-auth-service/.../config/RabbitMqConfig.java + infrastructure/messaging listeners |
| Event publisher | os-tickets-service/src/events/event-publisher.service.ts |
| Event consumer | os-integration-service/src/notifications/ + src/messaging/messaging-config.ts |