Orkun
Orkun

Reputation: 7268

Vertx : how to separate routers to a different class keeping a single verticle

We have a MainVerticle which is growing with the number of routes such as :

router.get("/vehicles/:id").handler(ctx -> {
        LOG.info("Entering get vehicle details");
        getVehicleDetailsCounter.inc();
        vehicleApiImpl.getVehicleDetails(ctx, httpClient);
    });

    router.post("/vehicles/:id/journey").handler(ctx -> {
        // BOOK VEHICLE
        LOG.info("Entering book vehicle");
        startJourneyCounter.inc();
        vehicleApiImpl.startJourney(ctx, httpClient);
    });

    router.post("/vehicles/:id/trips/:tripId/reports").handler(ctx -> {
        LOG.info("Entering trip reports");
        tripReportsCounter.inc();
        getTripReports(ctx, httpClient);
    });

    router.get("/availableVehicles/:cityId").handler(ctx -> {
        LOG.info("Entering available vehicles");
        availableVehCounter.inc();
        getAvailableVehicles(ctx, httpClient);
    });

    router.get("/zonesDetails/:cityId").handler(ctx -> {
        LOG.info("Entering zones details");
        getZonesDetailsCounter.inc();
        vehicleApiImpl.getZonesDetails(ctx, httpClient);
    });

    router.get("/models").handler(ctx -> {
        LOG.info("Entering models");
        modelsCounter.inc();
        vehicleApiImpl.getModels(ctx, httpClient);
    });

    router.get("/options").handler(ctx -> {
        LOG.info("Entering options");
        optionsCounter.inc();
        vehicleApiImpl.getOptions(ctx, httpClient);
    });
    
    // ============================
    // USER
    // ============================
    LOG.info("Handler register : USER");

    // Payment Details
    router.post("/user/notifyAppPaymentTransaction").handler(ctx -> {
        LOG.info("Entering payment transaction");
        notifyAppPaymentTransaction(ctx, httpClient);
    });

    // The user current journey
    router.get("/user/currentJourney").handler(ctx -> {
        LOG.info("Entering get current journey");
        getCurrentJourneyCounter.inc();
        userApiImpl.getCurrentJourney(ctx, httpClient);
    });

    // Create a new user
    router.post("/users").handler(ctx -> {
        LOG.info("Entering create user");
        createUserCounter.inc();
        createUser(ctx, httpClient);
    });

...

We need to keep listening to a single IP : port. What would be a good idea to break this MainVerticle into several classes while keeping the single verticle?

One obvious way would be static helper classes that take in the router and do the mappings inside. But in case there is an existing pattern in Vertx, using routers for example, it would really help.

Upvotes: 1

Views: 1633

Answers (2)

Jonathan Baptist
Jonathan Baptist

Reputation: 36

// Main Clss    
class Main : AbstractVerticle() {
    override fun start() {
        val router = Router.router(vertx)    
        router.route().handler(BodyHandler.create())
        router.get("/vehicles/:id").handler { req -> Controller.get_vehicle(req)}
        router.get("/vehicles/:id/journey").handler{req-> Controller.startJourney(req)}
    }
}

// Controller Class
open class Controller {
    companion object {
        fun get_vehicle(routingContext: RoutingContext) {
            // enter code here
        }
    }
}

Upvotes: 1

taygetos
taygetos

Reputation: 3040

You can for example extract your vehicle routes in a different handler. Then in the handler you can choose to implement your business logic there or better send a message through the eventbus, consume that message in any other Verticle, do your business logic there, and reply with an answer for the message, which you will send as a response.

router.route("/vehicles/*").handler(VehicleHandler.create(vertx, router));

VehicleHandler

public interface VehicleHandler extends Handler<RoutingContext> {
    static VehicleHandler create(Vertx vertx, Router router) {
        return new VehicleHandlerImpl(vertx, router);
    }
}

VehicleHandlerImpl

public class VehicleHandlerImpl implements VehicleHandler {

    private Router router;

    public VehicleHandlerImpl(Vertx vertx, Router router) {
         this.router = router;
         router.get("/:id/").handler(this::getVehicle);
         router.post("/:id/trips/:tripId/reports").handler(this::postReports);
         router.post(":id/journey").handler(this::postJourney);      
    }

    @Override
    public void handle(final RoutingContext ctx) {
         router.handleContext(ctx);
    }

    private void getVehicle(RoutingContext ctx) {
         //Option A: do you business logic here
    }

    private void postReports(RoutingContext ctx) {
        //Option B: send an eventbus message, handle the message in the MainVerticle and serve the response here   
    }

    private void postJourney(RoutingContext ctx) {
        //Option C: send an eventbus message, handle the message in a new Verticle and serve the response here 
    }
}

Upvotes: 5

Related Questions