How to implement a dynamic router using ballerina?

39 Views Asked by At

https://www.enterpriseintegrationpatterns.com/patterns/messaging/DynamicRouter.html

I am working on implementing a mediator in Ballerina that serves as a dynamic router for incoming HTTP requests. The goal is to route these requests to the relevant service endpoint. I need to add new routings and remove existing routings during runtime.

Is Ballerina a suitable language for this task, and if so, could someone provide a basic code skeleton to get me started?

2

There are 2 best solutions below

0
On

Let's imagine a scenario resembling a food delivery platform, let's call it "QuickBite Connect." In this use case, restaurants dynamically register their availability to serve food at various times. This registration involves notifying a mediator about their presence.

The communication pattern involves the restaurants signaling their presence to the mediator when they are available and announcing their sign-off when they are not. Now, when a user places an order through QuickBite Connect, the dynamic router will direct the order to the appropriate restaurant based on their current availability.

import ballerina/http;

type Restaurant readonly & record {|
    string restaurantId;
    string restaurantUrl;
    "AVAILABLE"|"UNAVAILABLE" status;
|};

// store the mapping of <Restaurant Id : Restaurant Url>
isolated map<http:Client> routingTable = {};

service /api/v1/mediator on new http:Listener(8080) {
    isolated resource function post placeOrder(http:Request request) returns http:Response|error {
        string restaurantId = check request.getHeader("restaurantId");
        http:Client? restaurantEp;
        lock {
            restaurantEp = routingTable[restaurantId];
        }
        if restaurantEp is () {
            return error("restaurant not avaiable for service.");
        }
        // output channel
        return restaurantEp->/placeOrder.post(check request.getJsonPayload());
    }

    // control channel
    resource function post updateStatus(Restaurant restaurant) returns error? {
        if restaurant.status == "UNAVAILABLE" {
            lock {
                _ = routingTable.removeIfHasKey(restaurant.restaurantId);
            }
        } else {
            http:Client cl = check new (restaurant.restaurantUrl);
            lock {
                routingTable[restaurant.restaurantId] = cl;
            }
        }
    }
}
0
On

Other than dynamic routing you can use the conditional statements provided by the ballerina to implement static routing. https://ballerina.io/learn/by-example/#conditional-statements

Here is a link to implementing a content based router using conditional statements. https://ballerina.io/learn/integration-tutorials/content-based-message-routing/

If you want to learn more about implementing other EI patterns using ballerina refer to the below link. https://ballerina.io/learn/enterprise-integration-patterns/