Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

What is the best way to remove path fragments from resource paths?

Not applicable

Hi Apigee Community,

I have an API with /foo/bar/ as basepath and 8 resource paths. Depending on the resource path, the API call will go to a different target server, example:

API call Backend webservice call
http://proxypath.com/foo/bar/a/b/test/something?key=apikey targetservice11.com/target/test/something?key=apikey
http://proxypath.com/foo/bar/c/d/id/something?key=apikey targetservice22.com/target/id/something?key=apikey

I have an API where I would like to use BasePath like /foo/bar/ . Let's assume that this API Proxy has 8 different paths (resources?) like: /foo/bar/a/b, /foo/bar/c/d, /foo/bar/e/f... and for each of them I would like to create a different Conditional Flow, because each resource path goes to a different target endpoint.

First flow/resource will have a condition like:

<Condition>(proxy.pathsuffix MatchesPath "/a/b/**") and (request.verb = "GET")</Condition>

with target endpoint url:

targetpath.com/target/

This means that when I make an API call to this resource:

GET http://proxypath.com/foo/bar/a/b/test/something?key=apikey

then this call will be send to Target endpoint with path like:

GET targetservice11.com/target/a/b/test/something?key=apikey

The main problem is that the real target webservice accepts a request like

targetservice11.com/target/test/something?key=apikey

without the /a/b resource path. I do not want to send url fragment used in flow condition (in example /a/b) to Target Endpoint, so I would like to send to Target Endpoint request:

targetservice11.com/target/test/something?key=apikey

(with /a/b path fragment removed), but by default in Apigee everything after basepath will be attached to Target endpoint url.

Since I need to remove part of path suffix (in example /a/b) in all resources (different part in each one), I considered using a few mechanisms:

  • using AssignMessage policy for each resource, where I assign path suffix part to remove to variable:
    • <AssignMessage async="false" continueOnError="false" enabled="true" name="AssignMessage.AssignMessageSuffix">
          <DisplayName>AssignMessage.AssignMessageSuffix</DisplayName>
          <AssignVariable>
              <Name>conditional.path.suffix</Name>
              <Value>/a/b</Value>
              <Ref/>
          </AssignVariable>
          <AssignVariable>
              <Name>target.copy.pathsuffix</Name>
              <Value>false</Value>
          </AssignVariable>
          <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
          <AssignTo createNew="false" transport="http" type="request"/>
      </AssignMessage>
      		
    • later I use JS to create Target path suffix
    •  var path_suffix = context.getVariable("proxy.pathsuffix");
       var condition_suffix = context.getVariable("conditional.path.suffix");
       path_suffix = path_suffix.replace(condition_suffix, '');
       context.setVariable("newsuffix.to.attach", path_suffix);
      		
    • in this case I have to create AssignMessage policy for each resource, where I define fragment which I would like to not send to backend. So for each target endpoint I need to create such an AssignMessage.
  • using single JS with condition for each resource (example might not work fine, but it captures the idea):
    • var path_suffix = context.getVariable("proxy.pathsuffix");
      if(pathsuffix=="/a/b**" && requestverb=="GET") {
          path_suffix = path_suffix.replace("/a/b", '');
          context.setVariable("newsuffix.to.attach", path_suffix);
      } else if (pathsuffix=="/c/d**" && requestverb=="GET") {
          path_suffix = path_suffix.replace("/c/d", '');
          context.setVariable("newsuffix.to.attach", path_suffix);
      } else if () {
      }
      ...
      		
    • this requires creating complex JS file, where most likely more than one condition will be checked (bad from performance reasons)

Which one of these solutions should I use in my proxies? Is there some easier or better way to deal with the problem? I have been also considering using different Proxy Endpoints, instead of resources. So, in our example, I would have 2 proxy endpoints. The first proxy would have basepath: /foo/bar/a/b/, while the second one would have the basepath: /foo/bar/c/d/. What do you think about this idea?

3 5 5,721
5 REPLIES 5