Using Java script policy for conditional routing

I have 2 target end points. How can I use Java script policy to route conditionally? Something like -

if(response.status.code = "404 || 400 || 502") {

route to Target End point 1

} else {

// Default

route to Target End point 2

}

0 9 557
9 REPLIES 9

@SaurabhSrivastava19

Routing happens before you send the request to the target and get the response.

The reason I am making this statement is, you are checking for response status code in your JavaScript. Not sure what exactly you are trying to do.

However in general, you can use this approach: set a flow variable in the JavaScript and check for its value in the routerule condition.

Eg:

In your javascript policy, which runs in the request flow somewhere:

if(condition1) {
  // route to Target End point 1
  context.setVariable("targetRouteTo", "target1");
} 
else {
  // Default
  // route to Target End point 2
  context.setVariable("targetRouteTo", "target2");
}

Then, later, In the RouteRules, you can use something like this:

<RouteRule name="target1">
  <Condition>targetRouteTo = "target1"</Condition>
  <TargetEndpoint>TargetEndpoint1</TargetEndpoint>
</RouteRule>
<RouteRule name="target2">
  <Condition>targetRouteTo = "target2"</Condition>
  <TargetEndpoint>TargetEndpoint2</TargetEndpoint>
</RouteRule>
<RouteRule name="default">
  <!-- used if neither of the other RouteRules has been applied -->
  <TargetEndpoint>DefaultTargetEndpoint</TargetEndpoint>
</RouteRule>

Thanks @Nagashree B. My use case is - I have a proxy where my target end point is a cache service which is returning response from cache. If anything goes wrong in cache service (e.g. if service is down) then I need to call actual service to get the response.

@SaurabhSrivastava19

I don't think you can route to another target endpoint in the response flow. You can try the below options

1. Use Apigee response caching if its feasible

2. Use a service callout to your backend service if the caching service is down

Thanks @Nagashree B. Apigee response caching was the best solution but we could not use it because response size is big. I tried service call out policy with DefaultFaultRule and seems its getting called. But how can I send back response from service call out (actual service) to the client. In my case client is getting response from first call (cache service which is 404 since I bring down the service for testing). Please suggest/share any example.

@SaurabhSrivastava19

In your flow add an assign message policy to overwrite the caching service response with the service callout response. Here is a sample

mocktargetapigee-1-rev1-2019-04-09.zip

trace-1554849783962.txt

Eg:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-Response">
<DisplayName>AM-Response</DisplayName>
<Properties/>
<Copy source="calloutResponse"/>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-1">
<DisplayName>Service Callout-1</DisplayName>
<Properties/>
<Request clearPayload="false" variable="request">
<Set>
<Verb>GET</Verb>
<Path>/get</Path>
</Set>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</Request>
<Response>calloutResponse</Response>
<HTTPTargetConnection>
<Properties/>
<URL>http://httpbin.org</URL>
</HTTPTargetConnection>
</ServiceCallout>

Proxy Endpoint:

<Response>
	<Step>
                <Name>Service-Callout-1</Name>
                <Condition>response.status.code = 404</Condition>
            </Step>
            <Step>
                <Name>AM-Response</Name>
                <Condition>response.status.code = 404</Condition>
            </Step>
</Response>

Thanks a lot @Nagashree B. Seems I am very close to the solution 🙂

Just one more thing. I need to pass all request parameters and headers (getting from client app for calling caching service) to the actual service. How can I update assign-message policy for this?

@SaurabhSrivastava19 ,

Create a new assign message policy and add it before the service callout. Similar to copying the callout response, copy the incoming request into a new variable called my request and pass that variable as the service callout request object, by changing variable mapping to "myrequest"

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><br><AssignMessage async="false" continueOnError="false" enabled="true" name="AM-Copy-Request"><br>  <DisplayName>AM-Copy-Request</DisplayName><br>  <Properties/><br>  <Copy source="request"/><br>  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables><br>  <AssignTo createNew="true" transport="http" type="request">myrequest</AssignTo><br></AssignMessage>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-1"><br>  <DisplayName>Service Callout-1</DisplayName><br>  <Properties/><br>  <Request clearPayload="false" variable="request">….

mocktargetapigee-1-rev1-2019-04-10.zip

Thanks @Nagashree B. Now everything is working as expected 🙂

Few questions though -

In Target EndPoints why are we setting 4xx and 5xx as success code?

<Property name="success.codes">1xx,2xx,3xx,4xx,5xx</Property>

Is it to continue with calling servicecallout in case of 4xx or 5xx?

@SaurabhSrivastava19

As per your usecase, you want to call the actual backend if the first caching service call returns 404. Apigee treats 4xx and 5xx codes as errors by default. So the flow will be in error state and will not continue to the response preflow/postflow steps. If there are any fault rules defined, only those will be executed. The success codes property configuration tells Apigee which error codes are to be treated as successful backend calls. With that configuration, the 404 response code error handling can be customized in the proxy flow to suit your needs. I used a generic value in the sample, you can configure with specific values like

<Property name="success.codes">1xx,2xx,3xx,404</Property>

which denotes only 404 to be treated as success, but if there is a HTTP 400 or 401 error that will still be treated as an error.

Here is the documentation for your reference

By default, Apigee Edge treats HTTP code 4XX or 5XX as errors, and it treats HTTP code 1XX, 2XX, 3XX as success. This property enables explicit definition of success codes, for example,2XX, 1XX, 505treats any 100, 200 and 505 HTTP response codes as success.

https://docs.apigee.com/api-platform/reference/endpoint-properties-reference