This topic demonstrates the use of conditional statements to customize the behavior of an API proxy. Specifically, this topic explains how to conditionally transform an XML-formatted response message to JSON format, based on the value of the User-Agent HTTP header associated with the request message.
A common mechanism used to customize responses for mobile devices is the User-Agent HTTP header. This header is included in requests from all apps, so it can be used to identify clients running on mobile devices. You can use generic patterns in these headers to identify classes of mobile devices. (There is a lot of informative discussion on the web on this topic.)
Your base of client devices is likely to change over time, so it's not a good idea to code this logic into the API or backend service itself. It's preferable to decouple this logic and use policies instead. Using policies, you can update your API's behavior over time to accommodate new client types without impacting your internal developers or your consumer apps.
In this topic, you configure an API proxy to evaluate a conditional expression for each request that it receives. The expression identifies mobile devices by evaluating the value of the User-Agent header. If the User-Agent header identifies the client device as an iOS client, then the API proxy returns a JSON-formatted weather report.
Working with variables and conditions
Conditional behavior is implemented using a combination of variables, conditional operators, and regular expressions.
Two documents provide a reference on variables and conditions supported by the API Platform:
For example, to create a condition that evaluates the HTTP verb of a request:
<Condition>request.verb="GET"<Condition>
Converting a payload from XML to JSON
First, apply a policy to convert the XML-formatted response from the Weather API into JSON.
Under apiproxy/policies, create a file called ConvertToJSON.xml with the following contents:
<XMLToJSON name="ConvertToJSON"> <Options> </Options> <OutputVariable>response</OutputVariable> <Source>response</Source> </XMLToJSON>
The policy configuration above tells the API proxy to take the response message, perform a conversion from XML to JSON with default settings, and then write the result to the response. (If you are converting a request message from XML to JSON, you simply set both of these values to request.) The XMLToJSON policy type determines a set of reasonable defaults, which means that you only need to add configuration elements to craft XML into specific JSON structures. For instruction, refer to Convert XML to JSON
Since you want to convert responses from XML to JSON, you need to configure a response Flow to perform the conversion. To convert all response from XML to JSON before they are returned to the client app, configure the following ProxyEndpoint Response Flow.
<Flows>
<Flow name="Convert-for-devices">
<Response>
<Step><Name>ConvertToJSON</Name></Step>
</Response>
</Flow>
</Flows>
Import and deploy the configuration. When you invoke your API using the standard request, the response is formatted in JSON.
However, your goal is to only convert Weather reports into JSON when the requesting client is a mobile device. To enable such dynamic behavior, you must add a conditional statement to the Flow.
Creating conditional Flow
Conditional flows are used for conditional execution of logic. Multiple conditional flows can be defined per ProxyEndpoint or TargetEndpoint. If multiple conditional flows are configured in an endpoint, the conditional statements are evaluated sequentially until a condition evaluates to true.
The following example shows a single conditional flow named Convert-for-devices, configured in the ProxyEndpoint Response Flow.
<Flows>
<Flow name="Convert-for-devices">
<Condition>(request.header.User-Agent == "Mozilla")</Condition>
<Response>
<Step><Name>ConvertToJSON</Name></Step>
</Response>
</Flow>
</Flows>
For each request received from an app, the API Platform stores the values of all HTTP headers present as variables. If the request contains an HTTP header called User-Agent, that header and its value are stored as a variable called request.header.User-Agent.
Given the ProxyEndpoint configuration above, the API Platform checks the value of the request.header.User-Agent variable to see whether the condition evaluates to true.
If the condition does evaluate to true, that is, the value of the variable request.header.User-Agent equals Mozilla, then the conditional flows executes and the XMLtoJSON policy called ConvertToJSON is enforced. If not, the Flow is not executed, and the XML response is returned unmodified (in XML format) to the requesting app.
Importing and deploying changes
Run the Python deploy tool. Substitute the username, password, and organization for your account on enterprise.apigee.com for myname:mypass and myorg.
$ tools/deploy.py -u myname:mypass -o myorg -e test -n weatherapi -d simpleProxy
Writing ../simpleProxy/apiproxy/weatherapi.xml to apiproxy/weatherapi.xml Writing ../simpleProxy/apiproxy/policies/ConvertToJSON.xml to apiproxy/policies/ConvertToJSON.xml Writing ../simpleProxy/apiproxy/proxies/default.xml to apiproxy/proxies/default.xml Writing ../simpleProxy/apiproxy/targets/default.xml to apiproxy/targets/default.xml Imported new proxy version 3 Undeploying revision 2 in same environment and path: Environment: test Revision: 2 BasePath = / State: deployed
Testing the conditional flow
In this sample request, the HTTP User-Agent header is set toMozilla, causing the conditional statement to evaluate to true and the conditional flow Convert-for-devices to execute.
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
or, to pretty print where Python is available:
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282 | python -mjson.tool
Sample Response:
. . .
"yweather_forecast": [
{
"code": "11",
"date": "12 Dec 2012",
"day": "Wed",
"high": "55",
"low": "36",
"text": "Showers"
},
{
"code": "32",
"date": "13 Dec 2012",
"day": "Thu",
"high": "56",
"low": "38",
"text": "Sunny"
}
]
}
. . .
A request submitted without the User-Agent header, or with a different value than Mozilla, will result in an XML-formatted response.
$ curl http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
The unmodified XML response is returned.
Sample Response:
<yweather:forecast day="Wed" date="12 Dec 2012" low="36" high="55" text="Showers" code="11" /> <yweather:forecast day="Thu" date="13 Dec 2012" low="38" high="56" text="Sunny" code="32" />
Post questions to the Apigee Developer Forum.
Back to API Platform Developer Guide.