I recently came across a great tool for benchmarking your APIs. It’s a nodejs tool written by Matteo Figus. Complete documentation on the tool could be found here

In this post I will provide simple tutorial for anyone to use this tool for their API’s

 

  • Create a folder and run navigate to the folder using your tool of choice for running node commands. I use Git Bash. Run the following command to install the api-benchmark package. This would require node to be installed beforehand.
$ npm install api-benchmark

 

  •  Now let’s add a new JavaScript file and name it as mybenchmark.js. We will require the benchmark tool
var apiBenchmark = require('api-benchmark');

 

  •  In this example we will use the Giphy API. Giphy is a GIF search engine. So let’s define a few variables that we will use.
var service = {
  server1: "http://api.giphy.com/"
};
var apiKey = 'dc6zaTOxFJmzC'; // public beta key

 

  •  Let’s add the routes which we want to test. In this example we will get the trending gifs.
var routes = {
		trending: {
			method: 'get',
			route: 'v1/gifs/trending?api_key=' + apiKey,
			headers: {
				'Accept': 'application/json'
			}
		}};

 

  •  And finally we run the benchmark
apiBenchmark.measure(service, routes, function(err, results){
	console.log(results);
});

 

  •  Here is the complete code of mybechmark.js for your convinence
var apiBenchmark = require('api-benchmark');

var service = {
  server1: "http://api.giphy.com/"
};
var apiKey = 'dc6zaTOxFJmzC'; // public beta key

var routes = {
		trending: {
			method: 'get',
			route: 'v1/gifs/trending?api_key=' + apiKey,
			headers: {
				'Accept': 'application/json'
			}
		}};

apiBenchmark.measure(service, routes, function(err, results){
	console.log(results);
});

 

  •  To see this in action we will run the benchmark by running the following command in your console.
$ node mybenchmark.js

 

  •  And you should see something like below.
Api-Benchmark 1

Api-Benchmark 1

 

 

  • This does show that our benchmark ran but we cannot interpret the results from here. To see that we will have to use the getHtml method available on api-benchmark.
apiBenchmark.measure(service, routes, function(err, results){
  apiBenchmark.getHtml(results, function(error, html){
    console.log(html);
  });
});

 

  •  However this will dump the entire html on the console which is nearly impossible to understand.
API Benchmark 2

API Benchmark 2

 

  • We will now save this html to a file so that we can view the results like the way it was intended. Let’s require another package to help us do that
var fs = require('fs');

 

  •  Change the apiBenchmark.measure to save the html in a file
apiBenchmark.measure(service, routes, function(err, results){
  apiBenchmark.getHtml(results, function(error, html){
    fs.writeFileSync('benchmarks.html', html);
  });
});

 

  •  To see this in action we will run the benchmark by running the following command in your console.
$ node mybenchmark.js

 

  • This would create a new html file (benchmarks.html) in your current folder with the results. It would look something like below. You see the details of your requests and your api is performing.
API Benchmark 3

API Benchmark Stats

 

  • It also has 2 more tabs which show Request Details and Response Details as well. All of this provides great insight into your APIs.
API Benchmark 4

API Benchmark Request Response

 

  • However I felt that if we could get the distribution of the api calls then it would provide deeper insight into my APIs. So I added a new tab to the report to showcase the distribtion of api calls overtime. The pull request is merged. So you would notice additional tab in the report i.e. distribution tab and you should see something like below

 

API Benchmark 5

API Benchmark Distribution

 

  • We could also specify the available options to benchmark the API’s deeply. Let’s try out a few
apiBenchmark.measure(service, routes, {
			debug: false,
			runMode: 'parallel',
			maxConcurrentRequests: 10,
			delay: 0,
			maxTime: 100000,
			minSamples: 100,
			stopOnError: false
		}, function(err, results){
	apiBenchmark.getHtml(results, function(error, html){
		fs.writeFileSync('benchmarks.html', html);
	});
});

 

API Benchmark Stats 100

API Benchmark Stats 100

 

API Benchmark Distribution 100

API Benchmark Distribution 100

 

Hope this helps you in getting started with api-benchmark. The entire source code for this post can be downloaded at googledrive or onedrive

 

Any questions, comments or feedback is always welcome.

 

Grunt is a JavaScript Task Runner. Any task runner is used for automating the repetitive tasks to increase productivity and efficiency.

Some of the automated tasks include

  • Implement standards
  • Unit Testing
  • End to end testing
  • Compiling
  • Automated task execution
  • File watching

Grunt is a command line tool available on the node platform. Once you have installed node, you would need to run the following command to make grunt command line available in your project.

npm install -g grunt-cli

To run grunt commands we would also require to create a Gruntfile.js because depending on the make of the grunt tool it looks for this file. Once we have this file then we could configure tasks inline, load tasks from external sources (files and modules), etc.

It’s always easy for me when I do some hand on so that’s what we would do. Create a new file named Gruntfile.js and add the following code to it.

 

// Code example to automate minification of an existing javascript file

module.exports = function(grunt) {

                // Load the plugin that provides the "uglify" task.

                grunt.loadNpmTasks('grunt-contrib-uglify');

                // Project configuration

                grunt.initConfig({

                                uglify: {

                                                target1: {

                                                                src: 'jquery-2.1.4.js',

                                                                dest: 'jquery-2.1.4.min.js'

                                                }

                                }

                });

                // Define the default task. 'default' is the alias to 'uglify'

                grunt.registerTask('default', ['uglify']);

}

 

Now move the folder where you created the Gruntfile.js and add a new file named as package.json. We will add the package that we care about which is uglify.

{

    "devDependencies": {

        "grunt-contrib-uglify": "^0.9.1"

    }

}

 

 

Download jQuery.version.js file or any other JavaScript that you would want to minify and add to the same folder

Now run the following command in your command line tool

  1. npm install -g grunt-cli
$ npm install -g grunt-cli

C:\Users\cshukla\AppData\Roaming\npm\grunt -> C:\Users\cshukla\AppData\Roaming\npm\node_modules\grunt-cli\bin\grunt

grunt-cli@0.1.13 C:\Users\cshukla\AppData\Roaming\npm\node_modules\grunt-cli

├── resolve@0.3.1

├── nopt@1.0.10 (abbrev@1.0.5)

└── findup-sync@0.1.3 (lodash@2.4.2, glob@3.2.11)

 

  1. npm init – fills all details is package.json
$ npm init

This utility will walk you through creating a package.json file.

It only covers the most common items, and tries to guess sane defaults.

See `npm help json` for definitive documentation on these fields

and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and

save it as a dependency in the package.json file.

Press ^C at any time to quit.

name: (FirstGruntTask)

version: (1.0.0)

description:

entry point: (Gruntfile.js)

test command:

git repository:

keywords:

author:

license: (ISC)

About to write to c:\FirstGruntTask\package.json:

{

  "devDependencies": {

    "grunt-contrib-uglify": "^0.9.1"

  },

  "name": "FirstGruntTask",

  "version": "1.0.0",

  "main": "Gruntfile.js",

  "scripts": {

    "test": "echo \"Error: no test specified\" && exit 1"

  },

  "author": "",

  "license": "ISC"

}

Is this ok? (yes) yes
  1. npm install grunt (for grunt dependencies.)
$ npm install grunt

npm WARN package.json FirstGruntTask@1.0.0 No description

npm WARN package.json FirstGruntTask@1.0.0 No repository field.

npm WARN package.json FirstGruntTask@1.0.0 No README data

grunt@0.4.5 node_modules\grunt

├── dateformat@1.0.2-1.2.3

├── which@1.0.9

├── eventemitter2@0.4.14

├── getobject@0.1.0

├── colors@0.6.2

├── rimraf@2.2.8

├── async@0.1.22

├── hooker@0.2.3

├── grunt-legacy-util@0.2.0

├── exit@0.1.2

├── nopt@1.0.10 (abbrev@1.0.5)

├── lodash@0.9.2

├── coffee-script@1.3.3

├── minimatch@0.2.14 (sigmund@1.0.0, lru-cache@2.6.2)

├── glob@3.1.21 (inherits@1.0.0, graceful-fs@1.2.3)

├── underscore.string@2.2.1

├── iconv-lite@0.2.11

├── findup-sync@0.1.3 (glob@3.2.11, lodash@2.4.2)

├── grunt-legacy-log@0.1.1 (underscore.string@2.3.3, lodash@2.4.2)

└── js-yaml@2.0.5 (esprima@1.0.4, argparse@0.1.16)

 

  1. npm install
$ npm install

npm WARN package.json FirstGruntTask@1.0.0 No description

npm WARN package.json FirstGruntTask@1.0.0 No repository field.

npm WARN package.json FirstGruntTask@1.0.0 No README data

grunt-contrib-uglify@0.9.1 node_modules\grunt-contrib-uglify

├── uri-path@0.0.2

├── chalk@1.0.0 (escape-string-regexp@1.0.3, ansi-styles@2.0.1, supports-color@1.3.1, has-ansi@1.0.3, strip-ansi@2.0.1)

├── uglify-js@2.4.21 (uglify-to-browserify@1.0.2, async@0.2.10, yargs@3.5.4, source-map@0.1.34)

├── maxmin@1.1.0 (figures@1.3.5, pretty-bytes@1.0.4, gzip-size@1.0.0)

└── lodash@3.8.0

 

 

  1. grunt
$ grunt

Running "uglify:target1" (uglify) task

>> 1 file created.

Done, without errors.

 

 

And boom we have created our first Grunt automated task to minify a JavaScript file.

You can download the source code @googledrive or @onedrive