Was this helpful?

This topic shows you how to write simple JavaScript that runs in an API proxy. You can use simple JavaScript to modify request or response messages, to parse message content, and to implement dynamic behavior.

In this topic you will learn how to use JavaScript to dynamically add HTTP headers to a response message and how to parse a JSON response and return only a small subset of its properties to the the requesting app.

Download and try out the sample code

Sample code: We recommend that you download and try out this topic's sample code from Github. The sample is called javascript-cookbook, which you can find in the doc-samples folder in the Apigee Edge API Services samples repository in Github. For information on downloading Apigee samples, see Using the samples

Instructions for deploying the API proxy and consuming the API are provided in the README file that comes with the sample. You can also find brief deployment instructions here: Deploying and testing samples.

About this cookbook example

This cookbook example illustrates an API proxy pattern in which you implement API behavior in JavaScript. The JavaScript examples are designed to show you how to work with simple variables and message content. One sample shows you how to get and set variables. The second example shows you how to parse JSON and construct a message from the result.

Two JavaScript samples are in the API proxy:

The code for setHeader.js:

context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"));
context.setVariable("response.header.X-Apigee-ApiProxyName", context.getVariable("apiproxy.name"));
context.setVariable("response.header.X-Apigee-ProxyName", context.getVariable("proxy.name"));
context.setVariable("response.header.X-Apigee-ProxyBasePath", context.getVariable("proxy.basepath"));
context.setVariable("response.header.X-Apigee-ProxyPathSuffix", context.getVariable("proxy.pathsuffix"));
context.setVariable("response.header.X-Apigee-ProxyUrl", context.getVariable("proxy.url"));
  • setHeaders.js: This JavaScript gets the values of a few variables that are set when an API proxy is invoked. The JavaScript adds those variables to the response message so that you can see their values for each request that you make.
  • minimize.js: This JavaScript shows you how to work with message content. The idea behind this sample is that a service often returns more data than is necessary. So, the JavaScript parses the response message, extracts a few interesting properties, and then uses them to build the content of the response message.

The code for minimize.js:

//Parse the original response from Yahoo weather
var originalResponse = JSON.parse(context.proxyResponse.content);
// Populate a variable with the orignal response object
var channel = originalResponse.rss.channel;
// Populate a variable with the minimized response object, extracting on the properties that we want to include in theh final response to the requesting app.
var minimizedResponse = { city: channel.location.city,
           country: channel.location.country,
           temperature: channel.item.condition.temp,
           conditions: channel.item.text,
           windSpeed: channel.wind.speed };
context.proxyResponse.content = JSON.stringify(minimizedResponse);

You can see that the base JavaScript object is a context. The context, in turn, exposes objects the represent messages at each processing stage. In this case, the JavaScript interacts with the proxyResponse, that is, the response message generated by the ProxyEndpoint. The proxyResponse, in turn, has a number of associated objects, (All of these objects are described in JavaScript object model.)

A useful exercise once you have the JavaScript working, is to modify these fields to use other values. For example, you can try changing the variable that sets the HTTP header by selecting a different variable from the list of Variables reference.
The sample proxy uses a policy of type XMLToJSON to convert the XML-formatted weather report into JSON. When working with JavaScript, you can always use this policy type to transform XML into JSON, making it easier for you to work with message content in JavaScript.

Before you begin

Before you explore this cookbook example, you should also be familiar with these fundamental concepts:

  • What policies are and how to attach them to proxies. For a good introduction to policies, see Policy attachment and enforcement.
  • The structure of a proxy flow, as explained in Flow configurations. Flows let you specify the sequence in which policies are executed by an API proxy. In this example, several policies are created and added to an API proxy flow.
  • How an API proxy project is organized on your filesystem, as explained in API proxy configuration reference.
  • A working knowledge of XML, JSON and JavaScript. In this example, you build out the API proxy and its policies with XML files that reside on the filesystem.

If you have downloaded the sample code, you can locate all of the files discussed in this topic in the javascript-cookbook sample folder. The following sections discuss the sample code in detail.

Going with the flow

To get JavaScript to execute in an API proxy, you have to attach it to a flow using a policy attachment called a 'Step'. A policy of type Javascript (note capitalization) simply contains a reference to the name of a JavaScript file. You point the policy to a JavaScript file using the ResourceURL element.

The Policy type must be capitalized appropriately in the Policy definition. Although "JavaScript" is the accepted spelling of the name of the programming language, in the Policy it must be capitalized as "Javascript".

For example, the following policy references the JavaScript file called setHeader.js.

<Javascript name='setHeaders' timeLimit='200'>
    <ResourceURL>setHeaders.js</ResourceURL>
</Javascript>
Always use the extension .js for JavaScript resources.

The maximum time limit permitted for JavaScript policies to execute in environments in free trial organization is 200 milliseconds.

You can attach this policy to an API proxy flow as you would any other policy type. By attaching the policy to the API proxy flow, you indicate where the JavaScript should be executed. This enables you to execute JavaScript that interacts with request messages or response message as those messages 'flow' through the API proxy. In this example, both JavaScripts execute in the response flow, since the policies do two things: set HTTP headers on the response message and 'minimize' the response message that Apigee Edge returns to the requesting app.

If you open this flow configuration in the management UI, you will see the flow configuration below.

Select Proxy Endpoints > default > PostFlow in the Navigator pane.

The corresponding XML configuration for the ProxyEndpoint named 'default' is shown below. 

<ProxyEndpoint name="default">
  <PostFlow>
    <Response>
      <!-- Steps reference policies under /apiproxy/policies -->
      <!-- First, set a few HTTP headers with variables for this transaction. -->
      <Step><Name>setHeaders</Name></Step>
      <!-- Next, transform the weather report from XML to JSON for easier parsing with JavaScript -->
      <Step><Name>transform</Name></Step>
      <!-- Finally, use JavaScript to create minimized, mobile-friendly weather report. -->
      <Step><Name>minimize</Name></Step>
    </Response>
  </PostFlow>
  <HTTPProxyConnection>
        <!-- BasePath defines the network address for this API proxy. See the script 'invoke.sh' to see how the complete URL for this API proxy is constructed.-->
    <BasePath>/javascript-cookbook</BasePath>
     <!-- Set VirtualHost to 'secure' to have this API proxy listen on HTTPS. -->
    <VirtualHost>default</VirtualHost>
  </HTTPProxyConnection>
  <RouteRule name="default">
    <TargetEndpoint>default</TargetEndpoint>
  </RouteRule>
</ProxyEndpoint>

Here's a summary of the flow's elements.

This is a ProxyEndpoint flow. The ProxyEndpoint configuration defines the inbound (app-facing) interface for an API proxy. When you configure a ProxyEndpoint, you define how apps invoke the proxied API.

  • <Request> - The <Request> element consists of several <Step> elements. Each step calls one of the policies that you create through the rest of this topic. These policies attach a JavaScript to the API proxy flow, and the location of the policy attachment determines when the JavaScript executes.
     
  • <Response> - The <Response> element also includes <Steps>. These steps also call policies that are responsible for processing the final response from the target (which in this example is the Yahoo weather API--note the HTTPTargetConnection setting in under /apiproxy/targets/default.xml.)
     
  • <HTTPProxyConnection> - Specifies the host and URI path that define the network address that apps call to consume this API.
     
  • <RouteRule> - This element specifies which TargetEndpoint configuration is invoked by the ProxyEndpoint.

Storing JavaScript as a resource

JavaScript (like Python scripts, Java JAR files, XSLT files, and so on) are stored as resources. When you are just starting to work with JavaScript it is easiest to store your JavaScript files in the API proxy. As you advance, JavaScript should be made as generic and reusable as possible, and then stored at the environment or organization level. This prevents you from having to store the same JavaScript files in multiple API proxies, which can quickly become unmanageable.

To learn about storing resources at the organization and environment level, see Resource files.

Importing and deploying the API proxy

After you make changes, you can Save the API proxy in the API proxy builder tool in management UI.

Or you can run the following command in the directory /api-platform-samples/doc-samples/javascript-cookbook.

$ sh deploy.sh

Testing JavaScript

Run the following command in the directory /api-platform-samples/doc-samples/javascript-cookbook.

$ sh invoke.sh

The curl flag -v is used in the shell script to view HTTP headers on the response message modified by the JavaScript.

You can directly submit a request as follows:

$ curl -v http://{org_name}-test.apigee.net/javascript-cookbook 

If the JavaScript executes properly, you will see a response like the following:

< X-Apigee-Demo-Target: default
< X-Apigee-Demo-ApiProxyName: simple-javascript
< X-Apigee-Demo-ProxyName: default
< X-Apigee-Demo-ProxyBasePath: /javascript-cookbook
< X-Apigee-Demo-ProxyPathSuffix: /forecastrss
< X-Apigee-Demo-ProxyUrl: http://rrt009ea.us-ea.4.apigee.com/javascript-cookbook/forecastrss?w=12797282
< Content-Length: 81
< 
{"city":"Palo Alto","country":"United States","temperature":"52","windSpeed":"5"}

You can now modify the JavaScript to try new things, redeploy the API proxy, and verify the results by submitting the same request. Always make sure you deploy the API proxy that contains your JavaScript to have your changes take effect.

Dynamically setting the target URL

Another common usage of JavaScript is to implement simple dynamic behavior based on variables. One example of this is setting the target URL for outbound requests. You might need to set the outbound URL dynamically based on payload content or on other contextual information.

In this example, you write JavaScript that sets a variable based on the value of another variable that it gets. Continuing with the reference example that proxies the Yahoo! weather API, we can write JavaScript to set the value of target.url based on the value that it gets from the variable path.uri. The effect of this JavaScript is to extract the WEOID query parameter from the request, and then to set it as the target URL for the outbound request.

This logic is implemented in the following JavaScript:

context.setVariable("target.url", "http://weather.yahooapis.com/forecastrss?w="+context.getVariable("path.uri"));

Script errors

You will inevitably see errors when writing JavaScript. The format of JavaScript errors that you will see issued by an API proxy is shown below.

{"fault":{"faultstring":"Execution of rewriteTargetUrl failed with error: Javascript runtime error: \"TypeError: Cannot find function getVariable in object TARGET_REQ_FLOW. (rewriteTargetUrl_js#1). at line 1 \"","detail":{"errorcode":"steps.javascript.ScriptExecutionFailed"}}}

When to use JavaScript

On Apigee Edge, there is usually more than one way to implement specific functionality. Use out-of-the-box policies where possible, and avoid the temptation to code all of your API proxy logic in JavaScript. Even though Apigee Edge leverages compiled JavaScript to improve performance, it is unlikely that JavaScript will perform as well as Policies. JavaScript may be more difficult to maintain and debug. Reserve JavaScript for functionality that is unique to your requirements.

If performance is a concern for custom functionality, use Java where possible.

Summary

In this cookbook topic, you learned how JavaScript can be included in an API proxy configuration to implement custom behavior. The custom behavior implemented by the samples demonstrate how to get and variables, and how to parse JSON and construct custom response messages.

Get help

For help, see Apigee Customer Support.

コメントを追加

Provide your email address if you wish to be contacted offline about your comment.
We will not display your email address as part of your comment.

We'd love your feedback and perspective! Please be as specific as possible.
Type the characters you see in this picture. (verify using audio)

Type the characters you see in the picture above; if you can't read them, submit the form and a new image will be generated. Not case sensitive.