How to convert a data of `byte[]` coming from RabbitMQ broker into a record type in Ballerina

75 Views Asked by At

I'm using RabbitMQ module in ballerina package along with a server and a client. In the client I'm receiving the content as a byte[] which needs to be converted to a CustomerDetails record type before processing. How can we do this?

client.bal

import ballerina/io;
import ballerinax/rabbitmq;

type CustomerDetails record {|
    string name;
    string ssn;
    string phone;
    int age;
|};

listener rabbitmq:Listener channelListener = new (rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT);

@rabbitmq:ServiceConfig {
    queueName: "MOT_HOTEL"
}
service rabbitmq:Service on channelListener {
    remote function onMessage(rabbitmq:AnydataMessage message) returns error? {
        if message.content is () {
            io:println("Message recived with `null` content");
        }
        io:println(message.content); // byte[]
        ...
    }
}

server.bal

import ballerina/http;
import ballerina/io;
import ballerinax/rabbitmq;

const queueName = "MOT_HOTEL";
const exchangeName = "TheExchange";

service /orders on new http:Listener(8080) {
    function init() returns error? {
        check rabbitmqClient->exchangeDeclare(exchangeName, rabbitmq:DIRECT_EXCHANGE);
        check rabbitmqClient->queueDeclare(queueName);
    }

    resource function post .(CustomerDetails payload)
                    returns http:Created|http:InternalServerError|error? {
        check rabbitmqClient->publishMessage({content: payload, routingKey: queueName});
        io:println("Message sent");
        return <http:Created>{};
    }
}
2

There are 2 best solutions below

0
On BEST ANSWER

You can use the CustomerDetails record instead of using rabbitmq:AnydataMessage as follows,

service rabbitmq:Service on channelListener {
    remote function onMessage(CustomerDetails customerDetails) returns error? {
        io:println(customerDetails.name); // you can handle fields here
    }
}

Refer https://ballerina.io/learn/by-example/rabbitmq-consumer/ example

0
On

If your requirement is to access all the details defined in the rabbitmq:AnydataMessage while having the content represented as a record type, you can define a custom record type using type inclusion, with your CustomerDetails record type as its content type as shown below.

public type CustomerDetailsMessage record {|
    *rabbitmq:AnydataMessage;
    CustomerDetails? content;
|};

Now, you can use this custom message type in your client code:

import ballerina/io;
import ballerinax/rabbitmq;

public type CustomerDetails record {|
    string name;
    string ssn;
    string phone;
    int age;
|};

public type CustomerDetailsMessage record {|
    *rabbitmq:AnydataMessage;
    CustomerDetails? content;
|};

listener rabbitmq:Listener channelListener = new (rabbitmq:DEFAULT_HOST, rabbitmq:DEFAULT_PORT);

@rabbitmq:ServiceConfig {
    queueName: "MOT_HOTEL"
}
service rabbitmq:Service on channelListener {
    remote function onMessage(CustomerDetailsMessage message) returns error? {
        if message.content is () {
            io:println("Message received with `null` content");
        }
        io:println(message.content); // CustomerDetailsMessage
    }
}