You are building a lightweight routing layer similar to how web frameworks match URLs to handlers.
Implement a Router that supports route patterns as explained below.
/ and segmented by /. Example: /bar/a/baz has segments ["bar","a","baz"]./foo/baz* that matches exactly one segment (not empty, no slashes). Example: /bar/*/baz matches /bar/a/baz and /bar/123/baz, but not /bar/a/b/c/baz.:, e.g. /users/:id. It matches exactly one segment too, and the segment value is captured as a parameter.When callRoute(path) is invoked, multiple patterns may match. Choose the winner using:
: param, which beats * wildcard.)If no routes match, return "NOT_FOUND".
Router()
void addRoute(String pathPattern, String result)
pathPattern is non-blank and starts with /.result is a non-blank string (server id to return).pathPattern again updates its result but preserves original insertion order.String callRoute(String path)
path is a concrete request path (no wildcards/params).result of the best matching pattern."NOT_FOUND" if nothing matches.List<String> searchRoutes(String wildcardPattern)
Allows querying stored routes using a wildcard pattern, returning all results whose patterns match that query.
Router router = new Router();
router.addRoute("/bar", "server-1");
router.callRoute("/bar"); // "server-1"
router.callRoute("/bar/xyz"); // "NOT_FOUND"
// Create a fresh router
Router router = new Router();
// Add a mix of patterns
router.addRoute("/bar/*/baz", "server-wild"); // wildcard
router.addRoute("/bar/:x/baz", "server-param"); // param
router.addRoute("/bar/a/baz", "server-static"); // fully static
router.addRoute("/bar/*/qux", "server-qux"); // different last segment
// Update an existing pattern (order stays where it was, result changes)
router.addRoute("/bar/*/baz", "server-wild-v2");
1) Wildcard query matches multiple stored patterns.
Returned in insertion order (not by precedence).
router.searchRoutes("/bar/*/baz");
returns ["server-wild-v2", "server-param", "server-static"]
2) Fully static query still matches param/wildcard patterns
that could match the same concrete path.
router.searchRoutes("/bar/a/baz");
returns ["server-wild-v2", "server-param", "server-static"]
3) Query with same length but different static segment.
router.searchRoutes("/bar/*/qux");
returns ["server-qux"]
4) Length mismatch => no matches.
router.searchRoutes("/bar/*/a/baz");
returns []
5) No compatible route at all.
router.searchRoutes("/nope/*");
returns []
Router router = new Router();
router.addRoute("/foo", "server-foo");
router.addRoute("/bar/*/baz", "server-bar");
router.callRoute("/foo"); // "server-foo"
router.callRoute("/bar/a/baz"); // "server-bar"
router.callRoute("/bar/x/baz"); // "server-bar"
router.callRoute("/bar/a/b/c"); // "NOT_FOUND" (pattern length mismatch)
Router router = new Router();
router.addRoute("/users/:id", "user-service");
router.addRoute("/users/:id/orders/:orderId", "order-service");
router.callRoute("/users/42"); // "user-service"
router.callRoute("/users/42/orders/7"); // "order-service"
router.callRoute("/users/42/orders"); // "NOT_FOUND"
Router router = new Router();
router.addRoute("/foo/baz", "server-foo");
router.addRoute("/foo/*", "server-bar");
// Both patterns match "/foo/baz".
// "/foo/baz" is more specific (static beats wildcard),
// so it wins regardless of insertion order.
router.callRoute("/foo/baz"); // "server-foo"
router.callRoute("/foo/xyz"); // "server-bar"
Router router = new Router();
router.addRoute("/a/:x/c", "server-1");
router.addRoute("/a/:y/c", "server-2");
// Both are equally specific and same length.
// Earlier added wins.
router.callRoute("/a/b/c"); // "server-1"