Responding to an HTTP request using RabbitMQ RPC

47 views
Skip to first unread message

Naresh Bhatia

unread,
Mar 16, 2017, 7:44:36 PM3/16/17
to rabbitmq-users
I am writing an API gateway which must accept HTTP requests from the front-end, collect the requested information using RabbitMQ messaging and finally return this information on the HTTP response. My approach is to use the RPC mechanism as described in the RabbitMQ example here. However it is not clear to me if this can work. My HTTP framework calls the getAccount() function shown below and expects the result in a promise. However if I structure the function similar to the RabbitMQ example, the message returned by the back-end service is nested inside the callback function supplied to channel.consume(). Thus the result is not available in the final then clause. Is there a way to do this?

getAccount(accountId) {

    let self = {
        conn: null,
        ch: null,
        replyToQ: null,
        correlationId: uuidV4()
    };

    return amqp.connect(url)
        .then((conn) => {
            self.conn = conn;
            return conn.createChannel();
        })
        .then((ch) => {
            self.ch = ch;
            return ch.assertQueue('', { exclusive: true });
        })
        .then((result) => {
            self.replyToQ = result.queue;
            // Set up a listener on the replyToQ
            return self.ch.consume(
                self.replyToQ,
                (msg) => {
                    if (msg.properties.correlationId === self.correlationId) {
                        // The result is available in the callback here, not in the final then clause!!!
                        const account = JSON.parse(msg.content.toString());
                        self.conn.close();
                    }
                },
                { noAck: true });
        })
        .then(() => {
            return Promise.all([
                self.ch.assertQueue(ACCOUNT_GET_QUEUE, { durable: true }),
                self.ch.sendToQueue(
                    ACCOUNT_GET_QUEUE,
                    new Buffer(JSON.stringify({accountId})),
                    { contentType: 'text/plain', correlationId: self.correlationId, replyTo: self.replyToQ })
            ]);
        });
}



Karl Nilsson

unread,
Mar 17, 2017, 5:42:20 AM3/17/17
to rabbitm...@googlegroups.com
Hi,

Ok without knowing or understanding nearly anything about javascript I think your getAccount function needs to return a promise that is resolved inside the consumer callback rather than the promise returned from setting up the subscription. How you would wire that up I don't know. Could you wrap all the above in a promise that is resolved in the consumer callback?

Cheers
Karl

--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitmq-users@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Karl Nilsson

Staff Software Engineer, Pivotal/RabbitMQ

Naresh Bhatia

unread,
Mar 18, 2017, 4:16:58 PM3/18/17
to rabbitmq-users
Thanks, Karl. Unfortunately from the API documentation for channel.consume() it is not clear what the returned promise resolves to. The channel.consume() function takes a callback which gets the message response. I am not sure if that can be returned to resolve the promise. A functioning example for this use case would be very useful.

Thanks.
Naresh
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-user...@googlegroups.com.
To post to this group, send email to rabbitm...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Naresh Bhatia

unread,
Mar 20, 2017, 3:59:00 AM3/20/17
to rabbitmq-users
To clarify, for a promises approach to work, the api must return a promise with the required response. This does not seem to be the way the the channel.consume() api is structured - it asks for a callback instead. That's where my mental block is at the moment.

Thanks.
Naresh
Reply all
Reply to author
Forward
0 new messages