Google is committed to advancing racial equity for Black communities. See how.

Implementing HTTP clients in JavaScript

In this cookbook example, you will learn how to create a mashup by attaching a JavaScript HTTP client to a proxy. This useful pattern lets you combine results from multiple backend targets using JavaScript to process requests and responses.

For a general overview of the HTTP client pattern, see "The JavaScript HTTP client pattern" in API Proxy Cookbook patterns.

Download and try out the sample code

About this cookbook example

This cookbook example illustrates an API proxy pattern that uses a JavaScript HTTP client object to call multiple backend services directly. As you will see, the JavaScript HTTP client code is attached as a policy to the ProxyEndpoint. In this case, the pattern does not require a TargetEndpoint; the HTTP client handles all communication with the backend targets. For a general overview of this pattern and other related ones, see API Proxy Cookbook patterns.

The example discussed here uses a custom HTTP client written in JavaScript to mash up data from these two separate public APIs:

  • The Google Geocoding API: This API converts addresses (like "1600 Amphitheatre Parkway, Mountain View, CA") into geographic coordinates (like latitude 37.423021 and longitude -122.083739).
  • The Google Elevation API: This API provides a simple interface to query locations on the earth for elevation data. In this example, the coordinates returned from the Geocoding API will be used as input into this API. This is a typical pattern where APIs are chained together using proxies.

The API surfaced through this proxy to app developers takes two query parameters: a postal code and a country ID. An app developer calls this proxy API like this:

$ curl "http://{myorg}"

The response is a JSON object that includes the geocoded location (latitude/longitude) for the center of the supplied postal code area combined with the elevation at that geocoded location.

  "country": "us",
  "postalcode": 80503,
  "location": {
    "latitude": 40.1724007,
    "longitude": -105.1960795
  "altitude": {
    "meters": 1570.249755859375,
    "feet": 5151.7380519886965

Before you begin

If you'd like to read a brief overview of the HTTP client pattern illustrated in this cookbook topic, see "The JavaScript HTTP client pattern" in API Proxy Cookbook patterns.

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. In this example, we build a single policy that wraps a JavaScript application. For a good introduction to policies, see What's a policy?.
  • The structure of an API proxy flow, as explained in Configuring flows. Flows let you specify the sequence in which policies are executed by an API proxy. In this example, a JavaScript policy is attached to the flow's ProxyEndpoint.
  • How an API proxy project is organized on your filesystem, as explained in API proxy configuration reference. This cookbook topic demonstrates local development (file system-based) as opposed to cloud-based development where you could use the management UI to develop the API proxy.
  • As you will see, this example uses two out-of-the-box API platform components: variables and the Apigee JavaScript Object Model. If you'd like to review details about these components now, see Variables reference and JavaScript object model.
  • A working knowledge of JavaScript and XML.

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

Going with the flow

Before moving to the JavaScript code, let's take a look a the main flow of our example API proxy. The flow XML, shown below, tells us a lot about this API proxy, and how the JavaScript application is integrated into the flow.

If you downloaded the sample from GitHub, you can find this API proxy definition in the file doc-samples/javascript-mashup-cookbook/apiproxy/proxies/default.xml.

<ProxyEndpoint name="default">
    <Flow name="default">
        <!-- Call the JavaScript that invokes both APIs and returns a response -->

    <!-- Add a base path to the proxy to distinguish from others in the environment -->
  <RouteRule name="default">
    <!-- No route. The proxy will return the request and not call a backend service. -->

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

  • <Request> - This API proxy does not use the <Request> element of the flow. In this pattern, the request is handled within the JavaScript application itself.
  • <Response> - The response part of the pipeline simply calls the JavaScript application, which handles the request from the client and all of the backend API calls.
  • <HttpProxyConnection> - Specifies details about how apps will connect to this API proxy, including the <BasePath>, which specifies how this API will be called.
  • <RouteRule> - The interesting thing about the <RouteRule> is that we don't specify one! That is, we don't specify a TargetEndpoint to invoke with <RouteRule>. With this pattern, there is no need to call the TargetEndpoint. The JavaScript application creates a response object that is returned to the client app.

Coding the JavaScript application

Here's the complete listing of our example JavaScript application. For the most part, it is straightforward JavaScript, with some Apigee-specific objects and variables mixed in. For convenience, these objects and variables are shown in bold type in the code. We'll discuss the Apigee-specific parts and how the are made available to the application immediately following the code.

// Initialize the response 
response.content = '';
response.headers['Content-Type'] = 'application/json';

try {
   if ((request.queryParams.postalcode == undefined) ||
       ( == undefined)) {
     throw '"postalcode" and "country" query parameters are required';

   // Send an HTTP GET to the URL that we construct
   var geocoding = httpClient.get(
        '' +
        request.queryParams.postalcode +
        '&region=' + +


    if (!geocoding.isSuccess()) {
        throw 'Error contacting geocoding web service';

    // We got a response. Parse the JSON into a JavaScript object.
    geocodeResponse = geocoding.getResponse().content.asJSON;

    if (geocodeResponse.status != 'OK') {
        throw 'Error returned from geocoding web service: ' + geocodeResponse.status;

    // Go through the JavaScript returned by Google and get the results
    var lat = geocodeResponse.results[0];
    var lng = geocodeResponse.results[0].geometry.location.lng;

    // Send another HTTP GET to the other service
    var altitude = httpClient.get(
        '' +
            lat + ',' + lng);


    if (!altitude.isSuccess()) {
        throw 'Error contacting altitude web service';

    altitudeResponse = altitude.getResponse().content.asJSON;

    if (altitudeResponse.status != 'OK') {
        throw 'Error returned from altitude web service: ' + altitudeResponse.status;

    var alt = altitudeResponse.results[0].elevation;    

    // Final assembly of the JSON object

    var body = response.content.asJSON; =;
    body.postalcode = request.queryParams.postalcode;
    body.location = { latitude: lat, longitude: lng}; 
    body.altitude = { meters : alt, feet : alt * 3.2808399};

} catch (err) {

    // Handle any error that may have happened previously by generating a response
    response.content.asJSON.error = err;
As mentioned previously, this code includes Apigee-specific variables and objects. The variables are included through the API proxy runtime environment. They include request, response, request.queryParams, response.content, and response.headers. These variables are populated whenever an app submits a request to the API proxy. For more information about variables and how they participate in the API proxy environment, see Variables reference.

The other Apigee-specific object is httpClient (Apigee's JavaScript HTTP Client). This object is part of the Apigee JavaScript Object Model. This object model defines request, response, and context objects with associated properties. It's purpose in this example is to make requests to backend services (the Google APIs) and return responses from those services. As with variables, the HTTP client is made available out-of-the-box to JavaScript applications that are deployed in an API proxy. For more detailed information on httpClient, see JavaScript object model.

Creating the JavaScript policy

To work within the context of an API proxy, we need to wrap the JavaScript application in a policy. The proxy references this policy at the point of attachment and immediately executes the JavaScript. (If you wish, refer back to the section "Going with the flow" to see where this policy is attached to the flow.)

If you downloaded the sample from GitHub, you can find this policy in the file doc-samples/javascript-mashup-cookbook/apiproxy/policies/MashItUp.xml.

<JavaScript name="MashItUp" timeout="10000">

Just a policy name and a reference to the JavaScript source file. Pretty simple.

Testing the example

If you have not already done so, try to download, deploy, and run the javascript-mashup-cookbook sample, which you can find in the doc-samples folder in the Apigee Edge samples repository on GitHub. Just follow the instructions in the README file in the javascript-mashup-cookbook folder. Or, follow the brief instructions here: Using the sample API proxies.

To summarize, you can call the API as follows. Substitute your {myorg} with your organization name:

$ curl "http://{myorg}"

The response is a JSON object that includes the geocoded location (latitude/longitude) for the center of the supplied postal code area combined with the elevation at that geocoded location. It also includes a conversion of the elevation from meters to feet. The data was retrieved from two backend APIs, mashed up inside the JavaScript application, massaged a bit, and returned to the client in a single response.

  "country": "us",
  "postalcode": 80503,
  "location": {
    "latitude": 40.1724007,
    "longitude": -105.1960795
  "altitude": {
    "meters": 1570.249755859375,
    "feet": 5151.7380519886965


This cookbook topic explained how to attach an HTTP client written in JavaScript to an Apigee API proxy. One use for a pattern like this is to create a mashup of data pulled from multiple backend services. At the same time, because the JavaScript is attached to the API proxy as a policy, it can participate in Apigee Edge features like traffic management, security, mediation, and analytics.