Architecture Pattern Guide

Event Processing and Handler Ownership

Goal

Routing is only the beginning. Something still has to receive the event, validate it, decide what reaction is needed, call dependencies, record outcomes, and fail safely.

That work belongs to an event handler.

The durable idea is:

Event handlers own the reaction, side effects, and recovery behavior for the events they consume.

The Short Version

An event handler is code that reacts to an event.

The simple question is:

Where should the handler run?

The better architecture question is:

What kind of processing is this, and what operating responsibility does it create?

Handlers may run as functions, containers, services, jobs, workflow steps, or dedicated workers. The runtime matters, but the handler responsibility matters more.

Event
  -> Handler runtime
  -> Validation and decision
  -> Side effect
  -> Logs, metrics, retry, and ownership

What a Handler Owns

A handler does more than receive an event.

ResponsibilityWhy It Matters
ValidationThe handler should reject malformed, unexpected, or unauthorized events safely.
IdentityThe handler needs controlled access to storage, databases, queues, APIs, and secrets.
IdempotencyThe same event may arrive or be processed more than once.
Dependency callsDownstream APIs and data stores can fail, throttle, or return partial results.
StateThe handler may need to record progress, outcomes, or deduplication markers.
Retry behaviorTemporary failures should be retried carefully; permanent failures should become visible.
ObservabilityLogs, metrics, traces, and correlation IDs help teams understand asynchronous flow.

Managed runtimes can reduce infrastructure work. They do not remove application responsibility.

Choosing a Handler Runtime

A small focused handler may fit a serverless function. For example, a function can validate an event, extract metadata, update a projection, send a notification, or place durable work on a queue.

A heavier handler may fit a containerized worker. For example, a worker may need custom libraries, longer processing, specialized tooling, container deployment consistency, or background processing that consumes from a queue.

Use this decision frame:

QuestionSmall Function SignalContainer or Worker Signal
How focused is the task?One small event-triggered reaction.Broader worker responsibility.
How custom is the runtime?Standard runtime is enough.Custom image, tools, or libraries matter.
How long or heavy is processing?Short and lightweight.Longer, heavier, or dependency-rich.
How is it deployed?Function deployment fits team practice.Container image deployment fits team practice.
What operations are needed?Trigger scale and simple monitoring are enough.Worker scaling, queue depth, container logs, and runbooks matter.

This is not a ranking. A mature event-driven architecture may use both.

Example: Order Handlers

When OrderPlaced is published, several handlers may react:

HandlerReactionOwnership Concern
Inventory reservation starterCreates durable inventory work.Avoid duplicate reservations.
Customer notification handlerSends confirmation.Avoid duplicate messages and respect customer preferences.
Fraud signal handlerUpdates fraud analysis input.Protect sensitive data and trace correlation.
Analytics projection handlerUpdates reporting model.Handle replay without corrupting aggregates.

The order service does not own these side effects. Each subscriber team owns its handler, permissions, idempotency, failures, and telemetry.

Common Mistakes

  • Treating handlers as anonymous scripts.

  • Giving handlers broad permissions.

  • Ignoring duplicate events or retries.

  • Monitoring the router but not the handler side effects.

  • Letting many tiny handlers become a hidden workflow with no owner.

  • Calling downstream systems without timeout and failure classification rules.

If Someone Asks You

What does an event handler own?

A good answer is:

A handler owns the reaction to an event. That includes validation, identity, permissions, side effects, idempotency, dependency calls, retry behavior, local state, telemetry, and failure handling. The event source owns the fact; the handler owns what it does with that fact.

What You Should Remember

A handler owns the reaction, not the event source.

Questions to Check Understanding

  1. Why should handlers be idempotent?

  2. What signals should handlers emit?

  3. How does handler ownership differ from source ownership?