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).
foobar microservice is given the prefix
foo. Client requests are made for
/foo/baz, Kong matches them to the
foo route and makes upstream requests for
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.
We create new routes for
/baz. Client requests are still made for
/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
/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) end end
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.
- Issue HTTP redirects to
- 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-paththat 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?