Applying middleware before routing

Hey!
I am trying to use traefik as an application-layer balancer - that is, route traffic based on range of a certain header of the request: if the header's value is between, say, 0 and 1752 - route it into service-shard-1, between 1752 and 2134 - service-shard-2 etc.

Making a regexp that executes greater-or-equal operation with arbitrary ranges seems to be impossible, so I made a custom middleware plugin that does exactly what I want - takes the header, takes the predefined ranges from the config and, for example, sets another request header "X-Shard-Id" equal to 1, 2 or any other number. Now I can easily route this request with

rule: Header(`X-Shard-Id`, `2`)

The problem is - routing has already took place, as middleware executes after the rule match. So now the request is already on its way to service.

Possible options I could think of here are:

  1. Chain Redirect(?) MW after mine, so that is sends the updated request to another traefik entrypoint, which on its turn does all the routing. But how to do it exactly?
  2. Chain routers one after another - one updates the header, another does the actual routing. But it does not seem to be possible, as routers only route to services, not to each other (right?)
  3. Maybe its possible to do routing inside a middleware itself, but it kind of breaks the whole
    "chain of commands" here: entrypoint->router->service. MWs by its definition should not do such thing as routing.

Cognitively easiest solution is to just chain two different traefik instances, but we have hard SLAs here, so winning few ms does matter.

If anyone encountered and solved such problems - I'd really appreciate some advice.

The final target service instance can not be chosen by middleware AFAIK.

You could just send the request to yourself, but don’t need an extra entrypoint, but just additional router(s) (and services) that checks in rule for presence of dedicated header(s).