Hiep
Hiep

Reputation: 2612

Masstransit How to make Advanced request / reply pattern

I have 3 micro-services as following communicating via masstransit/rabbitmq

advance request reply

I'd like that the Api makes request to the TransactionService but got the response from the PspService.

namespace API
{
    //I wish to have something like this
    PaymentForm form = await requestClient.GetResponse<PaymentForm>(new CreatePayment())
}

namespace TransactionService
{
    public class CreatePaymentConsumer : IConsumer<CreatePayment>
    {
        public async Task Consume(ConsumeContext<CreatePayment> context)
        {
            context.Send<BuildPaymentForm>()
        }
    }
}

namespace PspService
{
    public class BuildPaymentFormConsumer : IConsumer<BuildPaymentForm>
    {
        public async Task Consume(ConsumeContext<BuildPaymentForm> context)
        {
            context.Response<PaymentForm>() //how to make sure that the response will be sent to the API, but not to the caller (TransactionService)?
        }
    }
}

Please point me to the right way to make this communication pattern or a similar example, or the right part in the documentation.

Upvotes: 1

Views: 640

Answers (1)

Chris Patterson
Chris Patterson

Reputation: 33288

You can copy the RequestId and ResponseAddress from the CreatePayment message to the message produced by the first consumer using the CreateCopyContextPipe method. There is also a built-in way to copy all headers to the outgoing message (which I've used below).

namespace TransactionService
{
    public class CreatePaymentConsumer : IConsumer<CreatePayment>
    {
        public async Task Consume(ConsumeContext<CreatePayment> context)
        {
            var pipe = context.CreateCopyContextPipe();

            await _otherHost.Publish(new BuildPaymentForm(...), pipe);
        }
    }
}

namespace PspService
{
    public class BuildPaymentFormConsumer : IConsumer<BuildPaymentForm>
    {
        public async Task Consume(ConsumeContext<BuildPaymentForm> context)
        {
            await context.RespondAsync(new PaymentForm(...));
        }
    }
}

The first consumer will publish the command to the second consumer, copying all headers to the outbound message. The second consumer will then respond to the request initiator.

Upvotes: 2

Related Questions