Search code examples
springspring-integrationmessagingspring-messaging

Hiding Spring Messaging Infrastructure from Clients


I am developing a service that makes use of Spring for messaging and integration. The service has an inbound message channel that clients can use to send control information to the service and an outbound message channel that the service can use to send event information to interested clients.

I would like for the service to be deployable in scenarios wherein clients are in different address spaces and use a messaging technology (e.g. zeromq or AMQP) for communicating with the service and also in scenarios wherein a client resides in the same address space as the service and uses basic POJO calls to communicate with the service.

In the latter case - client and service in the same address space - it is clear enough to me how I can use something like MessagingGateway to hide the messaging infrastructure for calls from the client to the service. It is not as clear to me, however, how I would hide the messaging infrastructure from clients wishing to receive event information asynchronously from the service.

What is the preferred way of using Spring Integration to do this?


Solution

  • ZeroMQ does not have a persistent storage to be treat as a messaging broker. And technically there is just no any intermediary we can rely on. As long as there is one of the side of the communication, we lose our data. That's my five fingers about ZeroMQ binder.

    With plain Spring Integration, when you still want to use ZeroMQ channel adapters as a contract between apps and what to hide the messaging infrastructure from target users, you indeed can use that @MessagingGateway for sending.

    For receiving asynchronously (aka subscribing), I would suggest to look into a Reactor Flux support on the integration flows. One of the choice is to use an IntegrationFlowDefinition.toReactivePublisher(). Another one is to use Flux.from(FluxMessageChannel). Then you just use all those Reactor operators to bring a high-level API for end-user to subscribe to this stream and consume.

    See more in docs: https://docs.spring.io/spring-integration/docs/current/reference/html/reactive-streams.html#reactive-streams

    In the end, of course, you can use Spring Cloud Stream with its functional support to let end-user only to concentrate on a business logic of some microservice. Only the problem for you that there is no ZeroMQ binder and probably won't be.