Minimal publisher + consumer. Durable topic exchange, persistent messages, manual ACKs.
docker compose up -d
Management UI: http://localhost:15672 (demo/demo)
dotnet run --project src/ConsumerWorker/ConsumerWorker/ConsumerWorker.csproj
dotnet run --project src/ProducerApi/ProducerApi/ProducerApi.csproj
http://localhost:5187/ordersContent-Type: application/json{
"amount": 149.99,
"customerId": "CUST-1001"
}
You should see 202 Accepted in Postman, a “Published …” log in the API console, and a “Received … ACK” log in the consumer console.
curl -X POST http://localhost:5187/orders ^
-H "Content-Type: application/json" ^
-d "{ \"amount\": 149.99, \"customerId\": \"CUST-1001\" }"
demo.events (topic, durable)order.created.v1demo.order.created.q (durable, prefetch=10, manual ACK)DeliveryMode = 2)
All GIFs are kept short (≤40s) and ~960px wide for quick loading.
// Producer (excerpt)
await using var conn = await factory.CreateConnectionAsync();
await using var ch = await conn.CreateChannelAsync();
await ch.ExchangeDeclareAsync("demo.events", ExchangeType.Topic, durable: true, autoDelete: false);
await ch.BasicPublishAsync(exchange, routingKey, mandatory: true, basicProperties: props, body: body);
// Consumer (excerpt)
await ch.BasicQosAsync(0, prefetchCount: 10, global: false);
var consumer = new AsyncEventingBasicConsumer(ch);
consumer.ReceivedAsync += async (_, ea) => {
var json = Encoding.UTF8.GetString(ea.Body.ToArray());
var msg = JsonSerializer.Deserialize<OrderCreated>(json);
await ch.BasicAckAsync(ea.DeliveryTag, false);
};
await ch.BasicConsumeAsync("demo.order.created.q", autoAck: false, consumer);