Trigger re-routing in plugin?

Hi. I and my team have been using Kong extensively for over two years now as our API gateway and Kubernetes ingress controller. But we are now reevaluating our routing strategy and are trying to use a custom plugin to prevent any breaking changes, but it is not having the behaviour I am expecting.


Early on we adopted a straightforward routing approach where each of our services was given its own Route (ingress) based on a unique prefix. This route was configured in Kong with strip_path=true (at the time this was the default behaviour of KIC).

For example:
The foobar microservice is given the prefix foo. Client requests are made for /foo/bar and /foo/baz, Kong matches them to the foo route and makes upstream requests for /bar and /baz respectively.

This is obviously a very coarse approach and we are doing away with it for a variety of reasons. Essentially we would like to have the flexibility of working with more of the path without stripping it, matching to different Routes for the purposes of applying different plugins, or routing to different upstream services without breaking the external API by changing the prefix.


The decision was made to do away with these prefixes, but this poses another issue as removing them entirely would be a breaking change in our external API. We will eventually deprecate them according to our policies, but for now we aim to be able to handle a transition period through Kong.

For example:
We create new routes for /bar and /baz. Client requests are still made for /foo/bar and /foo/baz since they expect those to still work. A Kong plugin should strip /foo and then trigger a re-route based on the remaining path segment. The remaining /bar may still go to the foobar microservice, but /baz might have additional plugins applied, or route to a new foobaz microservice instead, and this cannot be allowed to be bypassed by clients still using the /foo prefix. External requests to /bar and /baz directly will skip the rerouting.

In a test implementation of this plugin, I have tried to do this using the ngx.req.set_uri function, with the jump argument set to true. As such this was done in the rewrite handler, and the plugin configured as global. Essentially:

function PathMigrator:rewrite(config)

  local matched
  local remainder_path
  -- Somehow set matched true/false based on whether or not a prefix was matched, and set remainder_path to the rest of the path without the prefix

  if matched then
    ngx.req.set_uri(remainder_path, true)

Unexpectedly, when this jump happens we do see (via logging) that the plugin re-triggers to handle the modified path but after plugin execution Kong still routes according to the original request path /foo/bar resulting in the “no Route matched with those values” 404 response.

Alternate options considered

  • Issue HTTP redirects to remainder_path
    • This would be my ideal approach but I am told that we may not be able to rely on our external clients to follow redirects
  • Create prefix-matching Routes with strip-path that route back to Kong and then Kong can handle the remainder as a new request
    • Puts double connection load on Kong

Given all this:
Is there any way to trigger a re-route like we are trying to do?
If not, are there any options other than those listed above that we should consider?