The handlers mounted on sub-router are ignored when the mount point is "/".
router.mountSubRouter("/", subRouter);
Note that, we can't have empty string as mount point.
It was functional until v3.8.1. With v3.8.4 it behaves as exactMatch and ending with slash.
Below table shows the difference between 3.8.1 and 3.8.4 based on the reproducer shared below:
| Path | v3.8.1 | v3.8.4 |
| --- | --- | --- |
| /primary | Success | Resource Not Found |
| /primary?query | Success | Resource Not Found |
| /primary/ | Success | Success |
| /primary/random | Resource Not Found | Resource Not Found |
| With subrouter mounted at /abc|
| /primary/abc | Success | Success |
| /primary/abc/ | Success | Success |
| /primary/abc?query | Success | Success |
By default, Vertx version is set to 3.8.4 in the reproducer. Change it to 3.8.1 to verify the behavior.
RouterTestMain given in the reproducer. Server will start listening on 8443curl http://localhost:8443/primary?queryI have gone through below issues, wondering if this change was intended?
First two scenarios return success response in v3.8.4 also if we attach the handlers directly to the primary router instead of sub router (set useSubRouters flag in RouterTestServer.java to false to verify the behavior).
However, raising this ticket as the behavior of sub router mounting has changed.
I've just added this test on 3.8 and master:
@Test
public void testMountOnRoot() throws Exception {
Router subRouter = Router.router(vertx);
subRouter.get("/primary").handler(ctx -> {
ctx.response().setStatusMessage("Hi").end();
});
router.mountSubRouter("/", subRouter);
testRequest(HttpMethod.GET, "/primary", 200, "Hi");
testRequest(HttpMethod.GET, "/primary?query=1", 200, "Hi");
testRequest(HttpMethod.GET, "/primary/", 200, "Hi");
testRequest(HttpMethod.GET, "/primary/random", 404, "Not Found");
}
And the test passes.
The issue is not reproducible on a test
@pmlopes ,
I just revisited the reproducer and your test above to understand the difference.
The behavior is observed when second level of sub-router is configured. It works fine with first-level sub-router.
@ramtech123 could you help me out adding the test case to the test above that will make it fail?
Hi @pmlopes
Thanks for the test. I updated the same as below to replicate the scenario.
@Test
public void testMountMultiLevel() throws Exception {
Router routerFirstLevel = Router.router(vertx);
router.mountSubRouter("/primary", routerFirstLevel);
Router routerSecondLevel = Router.router(vertx);
routerSecondLevel.get("/").handler(ctx -> {
ctx.response().setStatusMessage("Hi").end();
});
routerFirstLevel.mountSubRouter("/", routerSecondLevel);
// Below two scenarios will fail with 3.8.4 and higher, pass with 3.8.1 and lower.
testRequest(HttpMethod.GET, "/primary", 200, "Hi");
testRequest(HttpMethod.GET, "/primary?query=1", 200, "Hi");
// Below scenarios will pass
testRequest(HttpMethod.GET, "/primary/", 200, "Hi");
testRequest(HttpMethod.GET, "/primary/random", 404, "Not Found");
}
Most helpful comment
Hi @pmlopes
Thanks for the test. I updated the same as below to replicate the scenario.