11436 SSO

Custom API Behavior Using JavaScript and Apigee Edge

Rajiv Kilaparti
Jan 28, 2014

As an API developer, you are undoubtedly familiar with JavaScript. Apigee Edge enables you to leverage your experience with JavaScript to implement custom API behavior without having to change the code of your APIs or backend services.

Edge can be used as a managed container for executing your custom JavaScript. You write the custom logic, and Apigee provides the container, security, management, monitoring, and analytics.

You can combine Apigee's out-of-the-box policies with your own custom JavaScript to implement custom behavior securely and reliably.

However, writing custom behavior with your own custom JavaScript requires a familiarity with Apigee's JavaScript object model. JavaScript that executes in a browser relies on the "browser object model," or BOM. JavaScript that executes on Apigee Edge, however, relies on a message-oriented object model. This object model defines request, response, and context objects with associated properties.

Apigee's documentation gives you a good understanding of Apigee's message-oriented object model. Having gone through the process of implementing custom behavior using JavaScript, at a certain point you'll feel the need to unit test the code that you've written. The question then is: how?


Sparrow.js comes to the rescue by defining the request, response, and context objects with associated properties, which you can use to test the code that you've written for your proxies on Apigee Edge. You can do all this on your localhost or on a continous integration environment

Testing with Sparrow.js

Sparrow.js relies on Node.js to parse and execute custom JavaScript that you use on Apigee Edge. It also requires Node for HTTP interfaces. Let's start with the usage:

$ npm install -g sparrow.js
$ cd your_project && sudo npm link sparrow.js

We use Mocha to write our tests:

$ npm install -g mocha

Let's write a small JavaScript file, which can be used in the API proxy, as well in the unit tests. Yes, the source file can be used in the unit tests, as it is. The source file, and its unit test, are pretty simple, and need no further elaboration:

// File: ./src/int-str.js
var response_payload;
try {
    response_payload = JSON.parse(context.getVariable('response.content'));
} catch (e) {
  // do nothing
try {
    if (response_payload) {
        var o = response_payload;
        for (var k in o) {
            if (o.hasOwnProperty(k) && !isNaN(o[k])) {
                o[k] = String(o[k]);
      context.setVariable('response.content', JSON.stringify(response_payload));
} catch (e) {
    // do nothing

Let's write our unit test

// File: ./test/test.js

var sparrow = require('sparrow.js')
  , Context = sparrow.Context
  , httplib = sparrow.Http
  , Parser = sparrow.Parser;

 describe("Context", function() {
    var context;

    beforeEach(function() {
        context = new Context();

    afterEach(function() {

    it("should exec js from file, with apigee context", function() {
        var opts = {
            path: '../src/int-str',
            context: context

        var result = Parser(opts, function(result) {
            var payload = context.getVariable('response.content');

Execute the tests—with Sparrow

Before we start with execution, we all know that a unit test requires the setup of test data that it can consume. Sparrow has a command line interface that does that for you:

$ sparrow ./src/int-str.js
  • this will produce a test fixture file, next to the source JavaScript file (int-str.js)
  • open this file and populate the test data needed for your JavaScript file (see below)
  • here is a sample of test data that you can use in the fixtures file

// File: ./src/int-str-fixture.js

const test_data_1 = { // test data 1 for test case
    'access_token': 'some_token',
    'user_id': 123456789123456789123456789

const test_data_2 = { // test data 2 for test case
    'access_token': 'some_other_token',
    'user_id': 44444444444444444444444444

exports.flow_vars_1 = {
    "response.content": test_data_1

exports.flow_vars_2 = {
    "response.content": test_data_2

// the same test case will be executed
// with above test data variants, which
// are: flow_vars_1 & flow_vars_2

We have the source JavaScript, a test file for the source, and a test fixtures file, which sets up test data for the unit test. Now, all you need to do is execute mocha, which will in turn execute the unit test.

Below is the output that you'd see after mocha finishes test execution:

$ mocha --require should --reporter spec

     should exec js from file, with apigee context 

  1 passing (6ms)

So, with this, we now have a way to test the code that we deploy to Apigee Edge. 


Scaling Microservices