Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use Restlet router v. Component with multiple routes

I've created multiple routes using this code with components:

Component component = new Component();
component.getServers().add(Protocol.HTTP, port);
component.getDefaultHost().attach(pair.uriPattern, pair.restlet);
component.getDefaultHost().attach("/heartbeat", new HeartbeatRestlet());

My heartbeat code works.

But when I use a router as the pair.restlet above it doesn't work:

Router router = new Router();
Restlet fooHandler = new FooRouter();
Restlet barHandler = new BarRouter();

router.attach("/foo/{fooId}", fooHandler);
router.attach("/bar/{barId1}/{barId2}", barHandler);

The Restlet doc only gives an example of using a router with the Application class:

public class FirstStepsApplication extends Application {

    @Override
    public synchronized Restlet createInboundRoot() {
        Router router = new Router(getContext());
        router.attach("/hello", HelloWorldResource.class);
        return router;
    }
}

Actually using my router-based code gives the same effect as hitting a nonexistant URL.

So I'm asking:

  1. Is there any difference between what the router-based approach is supposed to achieve and the Component-based approach?
  2. Can I get this code to work using the router-based approach? As of now my only solution is to scrap the multiple routers and attach multiple components instead, which requires dealing with more legacy code.
like image 617
djechlin Avatar asked Nov 12 '22 06:11

djechlin


1 Answers

I can't see any problem to use routers on a virtual host attachment since Restlet allows to compound elements to build the request processing chain.

The problem here is that routers can support several routes and you use an exact matching mode (the default one in fact).

Let's take a sample. If pair.uriPattern contains /test and you have a router attached on this route. Only the path /test will be handled no matter what you specified on the router (except the empty route ;-)

I guess that you want to implement sub routes matching, so you should consider to use the starts with matching when attaching the router to the virtual host:

Router router = (...)

Component component = new Component();
component.getServers().add(Protocol.HTTP, port);
component.getDefaultHost()
             .attach(pair.uriPattern, router)
             .setMatchingMode(Template.MODE_STARTS_WITH);
component.getDefaultHost().attach("/heartbeat", new HeartbeatRestlet());

In this case, all the requests that starts with the value of pair.uriPattern will be handled by the router. So the router should be defined like that:

Router router = new Router();
router.attach("/something", yourRestlet1);
router.attach("/somethingelse", yourRestlet2);

In this case, we will have the following behavior:

  • Route pair.uriPattern + "/something" will be handled with yourRestlet1
  • Route pair.uriPattern + "/somethingelse" will be handled with yourRestlet2

In fact, such approach is a fine way to organize the code of applications.

Hope it helps you, Thierry

like image 161
Thierry Templier Avatar answered Nov 14 '22 21:11

Thierry Templier