How do I modify a path before chaining to a second proxy?

I have an existing proxy with a deprecated base path. I also have a newer proxy with a different base path. They are almost functionally identical. The newer one is cleaner and has fewer endpoints. I want to change the deprecated proxy so it chains to the newer proxy. But I need to modify the path for a couple of endpoints. Here's contrived example:

Older proxy paths:

  • GET /old/v1/pets
  • GET /old/v1/pets/{petId}
  • POST /old/v1/pets
  • GET /old/foo/v1/petfood

New proxy paths:

  • GET /new/v1/pets
  • GET /new/v1/pets/{petId}
  • POST /new/v1/pets
  • GET /new/v1/petfood

My old proxy uses a LocalTargetConnect with a Path set to /new.

The first thee paths for the old proxy are easily chained to the new proxy. I had that working within minutes.

What I want to do with the fourth path of the old proxy is change it to /v1/petfood before chaining to the new proxy. I don't want to clutter up the new proxy to handle these deprecated paths. As soon as the clients are updated (mobile apps, so it takes some time), I want to decommission the old proxy and have all the clutter go away.

I've tried using AssignMessage to modify the Path. I've tried modifying request.path using Javascript. I've tried setting target.url using Javascript. All these modifications seem to be ignored. The path used by the old proxy to invoke the new proxy is /new/foo/v1/petfood, which doesn't exist.

I'm trying to understand what is used for a URL when chaining and then how I can set that to what I need.

Solved Solved
0 5 445
1 ACCEPTED SOLUTION

Here's what I suspect is happening. When your first proxy handles the inbound request. like GET /old/foo/v1/petfood , the proxy.basepath is /old and the proxy.pathsuffix is /foo/v1/petfood.

When that proxy sends the outbound request to a target, whether a chained proxy or a regular external http target, the first proxy appends the proxy.pathsuffix to the outbound request, as a default behavior. So therefore you get /new/foo/v1/petfood as the full path for the outbound request.

You have some options for modifying that default behavior. These can be used together or separately.

  1. you can set the variable called target.copy.pathsuffix to false. Usually you'd do this with an AssignMessage or with a JavaScript callout that relies on context.setVariable(). To have this be effective, you need to set the variable within the target request context. To say it a different way, if you attach the policy that sets the variable to the ProxyEndpoint, it won't have any effect. If you attach the policy to a Request flow in the TargetEndpoint, it will be effective in the way I just described here.
  2. use a <Path> element in the LocalTargetConnection configuration in the TargetEndpoint, and specify a variable there. This might look like:

    <LocalTargetConnection>
    <Path>{variable-containing-fullpath-here}</Path>
    </LocalTargetConnection>

    You would be responsible for setting that variable that contains the intended path. Also, you cannot use the Path element along with the APIProxy element.  It's one or the other. I am not sure which one takes precedence. AFAIK it is not documented.

  3. Explicitly set the target.url variable to the value you prefer. As with target.copy.pathsuffix, you must attach this in the Request flow for the TargetEndpoint. This will override any "inferred" path. It supercedes everything else.  I guess this would work with LocalTargetConnection and the APIProxy child element.

There are some related questions on the community site that you may find useful. search

In summary, what you are observing and reporting is expected behavior and you can modify that behavior via a few documented ways that allow you to remap paths conditionally in the proxy. 

View solution in original post

5 REPLIES 5

Here's what I suspect is happening. When your first proxy handles the inbound request. like GET /old/foo/v1/petfood , the proxy.basepath is /old and the proxy.pathsuffix is /foo/v1/petfood.

When that proxy sends the outbound request to a target, whether a chained proxy or a regular external http target, the first proxy appends the proxy.pathsuffix to the outbound request, as a default behavior. So therefore you get /new/foo/v1/petfood as the full path for the outbound request.

You have some options for modifying that default behavior. These can be used together or separately.

  1. you can set the variable called target.copy.pathsuffix to false. Usually you'd do this with an AssignMessage or with a JavaScript callout that relies on context.setVariable(). To have this be effective, you need to set the variable within the target request context. To say it a different way, if you attach the policy that sets the variable to the ProxyEndpoint, it won't have any effect. If you attach the policy to a Request flow in the TargetEndpoint, it will be effective in the way I just described here.
  2. use a <Path> element in the LocalTargetConnection configuration in the TargetEndpoint, and specify a variable there. This might look like:

    <LocalTargetConnection>
    <Path>{variable-containing-fullpath-here}</Path>
    </LocalTargetConnection>

    You would be responsible for setting that variable that contains the intended path. Also, you cannot use the Path element along with the APIProxy element.  It's one or the other. I am not sure which one takes precedence. AFAIK it is not documented.

  3. Explicitly set the target.url variable to the value you prefer. As with target.copy.pathsuffix, you must attach this in the Request flow for the TargetEndpoint. This will override any "inferred" path. It supercedes everything else.  I guess this would work with LocalTargetConnection and the APIProxy child element.

There are some related questions on the community site that you may find useful. search

In summary, what you are observing and reporting is expected behavior and you can modify that behavior via a few documented ways that allow you to remap paths conditionally in the proxy. 

I got it working by setting target.url using a Javascript policy. I tried different ways trying to use a variable in the <Path> element, but it doesn't seem to do variable substitution like it does for an <HTTPTargetConnection>. So my <Path> is /new and I just set the target.url by concatenating target.url (incoming value), proxy.pathsuffix (after removing /foo), a question mark, and request.querystring. Here's my entire JS code:

var path = context.getVariable("proxy.pathsuffix");
var queryString = context.getVariable("request.querystring");
var targetUrl = context.getVariable("target.url");
var remainingPath = path.replace(/\/foo/i, "");
context.setVariable("target.url", targetUrl + remainingPath + "?" + queryString);

I also had an AssignMessage policy as part of it  when it was working. I used that to set request.path and then used request.path in the JS. But then I decided to just do all of it in JS.

Thanks for the help!

Nice.  Thanks for contributing your solution.

@lkurth Can you plz confirm if your solution is working by setting up the 'target.url' using the javascript as you mentioned along with using the proxy chaining i.e LocalTargetConnection by proxy name method?

Confirmed