Spring Boot adapter
com.babelqueue:babelqueue-spring plugs the Java core into Spring AMQP. Its
auto-configuration registers a MessageConverter that encodes/decodes the canonical
envelope, so Boot wires it into both the RabbitTemplate (producing) and your
@RabbitListener containers (consuming) — no manual setup.
Install
Maven:
<dependency>
<groupId>com.babelqueue</groupId>
<artifactId>babelqueue-spring</artifactId>
<version>1.0.0</version>
</dependency>
Gradle:
implementation("com.babelqueue:babelqueue-spring:1.0.0")
implementation("org.springframework.boot:spring-boot-starter-amqp")
Requirements: Spring Boot 3, Java 17+, RabbitMQ. The core
(babelqueue-core) comes transitively.
Configuration
# application.yaml
babelqueue:
default-queue: orders # written to meta.queue; used when no queue is given
Auto-configuration exposes one MessageConverter bean (BabelQueueMessageConverter)
and a BabelQueuePublisher. Both back off if your app defines its own. Boot’s
RabbitMQ auto-config injects the single converter into the RabbitTemplate and the
default listener container factory.
Produce
Inject BabelQueuePublisher. Its publish(...) methods return the message meta.id:
import com.babelqueue.spring.BabelQueuePublisher;
import java.util.Map;
import org.springframework.stereotype.Service;
@Service
class Orders {
private final BabelQueuePublisher babelQueue;
Orders(BabelQueuePublisher babelQueue) {
this.babelQueue = babelQueue;
}
void create() {
babelQueue.publish("urn:babel:orders:created", Map.of("order_id", 1042L), "orders");
}
}
Available overloads: publish(urn, data), publish(urn, data, queue),
publish(urn, data, queue, traceId), and — for a typed message implementing
com.babelqueue.PolyglotMessage — publish(message) / publish(message, queue).
Each message carries the contract AMQP properties: type = URN, correlationId =
trace_id, messageId = meta.id, plus x-attempts / x-schema-version /
x-source-lang headers, application/json and persistent delivery.
Consume
A normal @RabbitListener receives a decoded core Envelope; route by URN with
EnvelopeCodec.urn(...):
import com.babelqueue.Envelope;
import com.babelqueue.EnvelopeCodec;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
class OrderListener {
@RabbitListener(queues = "orders")
void onMessage(Envelope envelope) {
if ("urn:babel:orders:created".equals(EnvelopeCodec.urn(envelope))) {
var orderId = envelope.data().get("order_id");
// ... use envelope.traceId(), envelope.data()
}
}
}
Non-conformant messages (missing URN, unsupported meta.schema_version, blank
trace_id, or missing data) are rejected by the converter — route them to a
dead-letter exchange the usual Spring AMQP way.
Because the wire format is the canonical envelope, a message your Spring app consumes may have been produced by any BabelQueue SDK, and vice-versa.