Remapping many paths?

Hi,

 

I'm trying figure out how to take the ideas behind https://www.googlecloudcommunity.com/gc/Apigee/Change-Target-URL-while-using-target-server-configura... and do it for several paths in the same proxy in the least painful way.

For instance, if I had some legacy paths in my API that I wanted to remap to different backend paths, maybe something like:

/dogs/   => /canines/

/cats/     => /felines/

/birds/   => /avians/

Would the correct pattern be to create discrete policies for each of those transforms and execute them for each flow with the matching condition? Is there some way to parameterize a policy that I could reuse so I only created one policy but multiple usages of it? Or would you try to do this in some larger javascript mapping table?

 

Also, is there a reference docs somewhere for <Path> under the <HTTPTargetConnection>? I can't seem to find anything here: https://cloud.google.com/apigee/docs/api-platform/reference/endpoint-properties-reference

 

Thanks,

Eugene

 

 

0 4 241
4 REPLIES 4

If I were doing this, and there were a handful of paths to be remapped, I would consider

  • using a KVM, KVM lookup by incoming path and then assign the outbound path accordingly via the Path element and message template
  • Using a JavaScript policy, with settings obtained from.... either KVM or a properties file 

The first options requires a KVM lookup based on the inbound path. like this 

<KeyValueMapOperations name='KVM-Get-Path' mapIdentifier='nameOfMap'>
  <Scope>environment</Scope>
  <ExpiryTimeInSecs>300</ExpiryTimeInSecs>
  <Get assignTo='target-path'>
    <Key>
      <Parameter ref='proxy.pathsuffix'/>
    </Key>
  </Get>
</KeyValueMapOperations>

And then setting the path in the HTTPTargetConnection like this: 

  <HTTPTargetConnection> 
    <SSLInfo> 
      <Enabled>true</Enabled> 
    </SSLInfo> 
    <LoadBalancer> 
      <Server name="testserver"/> 
    </LoadBalancer> 
    <Path>{firstnonnull(target-path,proxy.pathsuffix)}</Path> 
  </HTTPTargetConnection> 

...which I think will use the target-path if it is set, proxy.pathsuffix if not.  

That won't work if the proxy.pathsuffix is variable. In other words if it has fixed and variable segments like this: /dogs/1234/toys/1ab38

That won't work because you won't have an entry in the KVM for every possible dynamic path.  You really just want to lookup on the first segment of the inbound path.  And in that case you will need to use ExtractVariables on the inbound path to get that leftmost segment. 

<ExtractVariables name='EV-1'>
   <Source>request</Source>
   <VariablePrefix>extracted</VariablePrefix>
   <URIPath>
      <!-- put the extracted value into extracted.leftmost -->
      <!-- NB: The Pattern is matched against pathsuffix (what comes AFTER the basepath) -->
      <Pattern ignoreCase='true'>/{leftmost}/{id1}</Pattern>
   </URIPath>
   <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</ExtractVariables>

 And then your KVM lookup would use that leftmost variable as the key parameter. 

But then your rewrite would need to be a little more savvy. At this point I would want to use JavaScript to do those kinds of rewrites. 

 

In short, 

if it's simple, use the KVM and the Path message template approach.

If there are dynamic paths, then probably JavaScript would be simpler. 

KVM. Nice. I think I need to start baking that into my head a bit more. Seems like its frequently the answer to a lot of the 'tricks' I need to learn.

BTW, is there a reference for HTTPTargetConnection that includes Path? I'm still not sure how I would discover that without this forum 🙂

As for the Path within HTTPTargetConnection, I am baffled..... I cannot find a reference for that either. My apologies. Let me get someone to fix that. Either our search is way off, or... the doc page doesn't exist.  (They amount to the same thing, really)  EDIT: internal reference to the doc bug: b/229631843. 

 

Ya, the KVM ... is a good spot to store general configuration stuff. 

If you have Apigee X or hybrid, you can also look into properties files

If you are not excited about using KVM (for whatever reason), or properties, then you can embed settings in a settings.js file that is slurped up by a JavaScript callout. I do it like this: 

 

<Javascript name='JS-Remap-Paths' timeLimit='200' >
  <IncludeURL>jsc://pathSettings.js</IncludeURL>
  <ResourceURL>jsc://remapPaths.js</ResourceURL>
</Javascript>

 

And then in pathSettings.js maybe looks like this: 

 

var pathmap = {
  "/dogs" : "/canines", 
  "/cats" : "/felines", 
  "/birds" : "/avians"
  ..
}; 

 

And then remapPaths.js might look like: 

 

var re1 = new RegExp('^(/[a-z]+)(/.+)$');
var pathSuffix = context.getVariable('proxy.pathsuffix');
var desiredTargetPath = pathSuffix;
var m = re1.exec(pathSuffix);
if (m) {  // sanity check
  var leftmostSegment = m[1];
  if (pathmap[leftmostSegment]) {
    // remap
    desiredTargetPath = pathmap[leftmostSegment] + m[2];
  }
} 
context.setVariable('desiredTargetPath',desiredTargetPath);

 

Actually the remap logic can look the same, regardless of whether you retrieve the pathmap from KVM, or properties, or a JS file. Which one you use depends on .. which one feels most easy to maintain.  

Keep in mind that if you embed the pathmap into the apiproxy itself, then a change in a pathmap requires a proxy redeploy.  With KVM, the data is external to the apiproxy, and you can change the KVM value and affect the mapping  without redeploying the API proxy. 

 

All good insights. From a "git repo manages the proxy" standpoint properties files might be a good fit, even with the re-deploy note.

Thanks again for the depth of answers!