Query Params conditionfor processing

Hi all i have a requirement where resource url could be of the form -

a. /{customer-id}/addresses/{address-key}

b. /{customer-id}/addresses/{address-key}?preferredShipping=true

c. /{customer-id}/addresses/{address-key}?preferredMailing=true

If query params are passed then I have to set the form-prameters that are differently named variables.

defaultShippingAddressCode={ {address-key} or defaultMailingAddressCode=

{ {address-key} depending upon query params set - the preferredmailing or preferredshipping

I also have to set the target URL to /xxx/preferredMailingLInk or xxx/preferredShipping link based on same query params. I don't want to create different target flow as only url value is different and would like to use a variable keeping in mind there may be new options being added in future.

What may be the best way to address this. Also, of URL of type a where query params are missing it should function fine.

thanks

2 2 2,258
2 REPLIES 2

Hi @Aakash Sharma,

I think there are multiple ways to do what you want. Here are some suggestions.

You can parse any parts of an incoming resource URL into flow variables using the Extract Variable policy with <URIPath> element. Put the policy on the ProxyEndpoint Preflow Request. For example, this pattern puts the customer-id and address-key parts of the path into variables called apigee.customer-id and apigee.address-key (note that the variable prefix is specified to be "apigee").

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="ParseResourcePath">
    <DisplayName>ParseResourcePath</DisplayName>
    <Properties/>
    <URIPath>
        <Pattern ignoreCase="false">/{customer-id}/addresses/{address-key}</Pattern>
    </URIPath>
    <Source clearPayload="false">request</Source>
    <VariablePrefix>apigee</VariablePrefix>
</ExtractVariables>

You can extract the query parameters easily by adding QueryParam elements as follows:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="ParseResourcePath">
    <DisplayName>ParseResourcePath</DisplayName>
    <Properties/>
    <URIPath>
        <Pattern ignoreCase="false">/{customer-id}/addresses/{address-key}</Pattern>
    </URIPath>
    <QueryParam name="preferredShipping">
        <Pattern ignoreCase="true">{preferredShipping}</Pattern>
    </QueryParam>
    <QueryParam name="preferredMailing">
        <Pattern ignoreCase="true">{preferredMailing}</Pattern>
    </QueryParam>
    <Source clearPayload="false">request</Source>
    <VariablePrefix>apigee</VariablePrefix>
</ExtractVariables>

Now you have all the information you need to set your target request form variables and the target URL. You can set these things in a JavaScript policy. Put the policy on the Target Endpoint Preflow Request. For example, something like this, where you're setting request.formparam message variable (these variables are well documented here). Also see the JavaScript Object model doc for information about coding JavaScript policies.

 if (context.getVariable("apigee.preferredShipping") == "true") {
     context.setVariable("request.formparam.defaultShippingAddressCode", context.getVariable("apigee.address-key"));
 } else {
     context.setVariable("request.formparam.defaultMailingAddressCode", context.getVariable("apigee.address-key"));
 }

Dynamically setting the target URL is just as easy. You can also do that in a JavaScript policy and there's an example of how to do it here.

Hope this helps.

Will

Hi Aakash,

I suppose you have a Proxy endpoint with a conditional flow, which looks something like this:

<Flow name='aakash-1'>
    <Condition>(proxy.pathsuffix ~/ "/*/addresses/*") and (request.verb = "GET")</Condition>
   ...

If I were you, within the request flow , I would insert a JavaScript step that parses the pathsuffix and query params, or maybe use request.uri, which includes the basepath as well as the queryparams, and then runs the appropriate logic, then sets the target.url.

Actually it is not effective to set target.url in the proxy request flow. So you will want to insert that step into the TARGET request flow, where the target.url can be effectively written.

And what would the JS look like? Probably it would rely on the old reliable URI.js. Then it would be something like this:

function joinUrlElements() {
  var re1 = new RegExp('^\\/|\\/$', 'g'),
      args = Array.from(arguments);
  return "/" + args.map(function(element){ return element.replace(re1,""); }).join('/');
}


function setTargetRequestDynamically() {
  // set the path, derived from the proxy.url
  var proxyUri = new URI(context.getVariable('proxy.url'));
  context.setVariable('inbound-proxy-url', proxyUri.toString());
  var proxyPath = proxyUri.path();
  var pathParts = proxyPath.split('/');
  var addressKey = pathParts[4];
  var customerId = pathParts[2];
  context.setVariable('customerId', customerId);
  context.setVariable('addressKey', addressKey);
  //var proxySearch = proxyUri.search();
  //console.log('proxySearch: ' + JSON.stringify(proxySearch));
  if (proxyUri.hasQuery("preferredShipping", true)) {
    context.setVariable('target.url', 
                        joinUrlElements(context.getVariable('customerId'),
                                        "preferredShipping"));
    context.setVariable('request.formparam.defaultShippingAddressCode', 
                        addressKey);
  }
  else if (proxyUri.hasQuery("preferredMailing", true)) {
    context.setVariable('target.url',
                        joinUrlElements(context.getVariable('customerId'),
                                        "preferredMailing"));
    context.setVariable('request.formparam.defaultMailingAddressCode',
                        addressKey);
  }
  else {
    context.setVariable('target.url',
                        joinUrlElements(context.getVariable('customerId'),
                                        "whatever"));
  }
}