Service Activator
The bridge between queue and API: receives a message, calls a service, handles the response — the classic gateway to legacy systems.
Problem
An existing business system (ERP, OMS, mainframe) exposes a sync API (SOAP, REST, RPC). The EDI hub publishes async messages. How to bridge both without changing the existing app?
Forces
- The business system often cannot become a queue consumer (no SDK, no possible modification).
- The service activator must handle retries, timeouts, and idempotency on the legacy API side.
- A legacy service exception must be wrapped and routed correctly (DLQ, retry, alert).
- The sync service latency caps parallelism on the activator side.
Solution
Introduce an activator component that consumes from the message broker, deserialises, prepares the request, invokes the sync API, awaits the response, then either ACKs (success) or retries/escalates (failure). The pattern pays on decoupling: the legacy app stays untouched, the hub handles all messaging complexity. Classic implementations: Apache Camel `<process>` with HTTP call, Spring Integration `<service-activator>`.
EDI implementation
In EDI, Service Activator is the most common way to integrate a non-Kafka-native ERP. A Camel consumer on `edi.orders` deserialises canonical JSON, calls an SAP endpoint via IDoc or OData, awaits the response, then publishes an `OrderImported` event. Associated patterns: Circuit Breaker around the legacy API call, Idempotent Receiver on the ERP DB side, Dead Letter Channel for non-retriable exceptions.
Anti-patterns
- Activator without timeout — a slow legacy service blocks the entire consumer pool.
- Activator without retry — a transient glitch sends everything to DLQ.
- Activator that mutates the message in place and ACKs before the legacy response — data loss if the legacy API fails.
- Activator that calls several services in cascade without a saga — inconsistencies on exception.
Related patterns
- Message Endpoint — parent concept.
- Circuit Breaker — protection around the sync call.
- Idempotent Receiver — legacy DB side.
- Dead Letter Channel — destination for exceptions.
Sources
- Hohpe G., Woolf B. — EIP, Service Activator (p. 532). www.enterpriseintegrationpatterns.com/patterns/messaging/MessagingAdapter.html
- Spring Integration — Service Activator. docs.spring.io/spring-integration/reference/service-activator.html