Dynamic upstream path per target

Is it possible to determine which upstream/target has been (will be?) selected to handle a specific request from within a plugin or pre/post-function? I have a unique requirement where different upstreams for the same service need a slightly different path depending on the upstream. For example, suppose I want a single route (/myroute) to load balance across multiple upstreams/targets:

/myroute -> upstream.datacenter1.com/path1
/myroute -> upstream.datacenter2.com/path2

The upstream path is configured on Kong’s “service” object, and there is only one service, so it’s not possible to have different paths for upstreams via configuration. But I could theoretically modify the upstream path in code IF I can determine which target Kong is going select to handle the request. I looked through the PDK functions, but did not see anything relevant. It looks like maybe the decisions about which target to use happen later, after plugin code has finished running. If that’s true, then my idea isn’t going to work. Thoughts?

Definately. Many of my targets are dynamically built in this fashion. Here is a rough example that could go in the access phase of your plugin:

function MyPlugin:access(conf)
MyPlugin.super.access(self)
local upstreamDomain = “someplace.com
if conditionOne == true then
upsteramDomain = “someOtherPlace.com
end
kong.service.set_target(upstreamDomain)
end

You can see this function in the PDK at https://github.com/Kong/kong/blob/master/kong/pdk/service.lua

So, you are selecting a target base on some criteria, but Kong ends up calling that target with the path that is defined on the service (i.e., always uses the same path).

What I am looking for is to change the upstream path based on the target that Kong has selected (i.e., let Kong load balancer pick the upstream + target, then change the path based on what target was selected).

Ah yes, I completely misunderstood. I fear I am still misunderstanding, but would this work?:


– Sets the path component for the request to the service. It is not
– normalized in any way and should not include the querystring.
@function kong.service.request.set_path
@phases access
@param path The path string. Example: “/v2/movies”
@return Nothing; throws an error on invalid inputs.
@usage
– kong.service.request.set_path("/v2/movies")
request.set_path = function(path)

from “https://github.com/Kong/kong/blob/master/kong/pdk/service/request.lua

I think set_path() is part of the equation. But I need to know the target that Kong’s load balancer has picked (or will pick?) in order to decide what the path should be.

If I’m willing to force the target myself (as you mentioned in the earlier reply), then I’d know the destination and could update the path appropriately. But if I want to let Kong’s load balancer choose a target, and then change the path based on the target that Kong has selected, that’s the piece I’m missing.

Gotcha, I got it now. I hope someone is able to help.