Path-based routing
A router is a dispatcher than routes incoming requests to other dispatchers based on the request's path. It can also execute middleware along this route.
These other dispatchers are registered with the router using map and mount methods.
mapassociates a dispatcher with a path in the router.For example, you can map path
/greeterto a chatbot service. It's an exact match. A request with path/,/greeter2or/greeter/foois not a match.In C#, you would write:
C#var router = new Router();router.Map("/greeter", chatbot);mountassociates a dispatcher with a path prefix in the router.For example, you can mount path-prefix
/userto an account service. A request with path/useror/user/foois a match. A request with path/,/user2is not a match.In C#, you would write:
C#var router = new Router();router.Mount("/user", account);
It is common to map leaf dispatchers such as services and mount sub-routers, but it's not a hard and fast rule.
You can map and mount the exact same path (for example, /greeter). The router will direct a request with path /greeter to the mapped dispatcher and a request with path /greeter/foo to the mounted dispatcher.
If a router does not find a mapped or mounted dispatcher for an incoming request's path, it returns a response with status code NotFound.
Sub-router
A sub-router is a router registered with another "parent" router. It has a prefix that corresponds to its mount point; it removes this prefix when it looks up a dispatcher registered via map or mount.
In C#, you can create a sub-router and mount it in a single step with the Route extension method:
var router = new Router();
// create a sub-router and mount it at /adminrouter.Route("/admin", subRouter => subRouter.UseDispatchInformation().Map("/superAdmin", root));The full path to the root service with this example is /admin/superAdmin. The admin sub-router removes /admin from the request's path before trying to match this path against entries in its map and mount dictionaries.
Installing a middleware in a router
A router can execute one or more middleware before handing over the request to a mapped or mounted dispatcher.
In C#, these middleware are registered with Use{Name} extension methods on class Router. For example:
Router router = new Router().UseLogger(loggerFactory).UseCompressor();router.Map("/greeter", new Chatbot());The order in which you install these middleware is often important. The first middleware you install is the first middleware to execute. With the example above, the logger middleware executes first, then calls DispatchAsync on the compressor middleware, and then finally the compressor middleware calls DispatchAsync on the Chatbot service mapped at /greeter.
The router always dispatches incoming requests to its registered middleware, even when it ends up returning a response with status code NotFound.