npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rapip

v2.1.0

Published

REST API Performance. Test APIs from the perspective of both a Mobile phone and a Node server

Downloads

1

Readme

RAPIP

[ra-peep] REST API Performance. Test APIs from the perspective of both a Mobile phone and a Node server.

This module will help you collect performance metrics of any REST API, giving you to not just the response time but how long it will take to parse, size and any compression used (currently only supporting gzip).

RAPIP uses Async/Await so needs Node 8 and Chrome 55

Set up

npm install --save RAPIP

Usage

const { server, client } = require('rapip');

Reference

client(api, headers, emulator, headless, url)

Start a mobile client performance audit, it uses the Lighthouse Nexus 5 emulator (https://github.com/GoogleChrome/lighthouse/blob/63b4ac14d0a871ade0630db2885edd7848843243/lighthouse-core/lib/emulation.js).

You will get results for both an XHR and Fetch request.

Parameters
  • api - Required. String url of the api you want to benchmark.
  • headers - Object of request headers you want to add to the api call.
  • emulation - Object for the emulation configuration.
    • cpuThrottling - Boolean for toggling CPU throttling (Default: true).
    • networkThrottling - Boolean for toggling Network throttling (Default: true).
  • headless - Boolean for toggling Chrome headless (Default: true).
  • url - String for the URL to run the framework (Default: "http://localhost:3000").
Response
{
  response: {
    api: 'https://httpbin.org/user-agent'
    emulation: {
      deviceEmulation: 'Nexus 5X',
      cpuThrottling: '4x slowdown',
      networkThrottling: '562.5ms RTT, 1.4Mbps down, 0.7Mbps up',
      userAgent: 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MRA58N) AppleWebKit/537.36(KHTML, like Gecko) Chrome/61.0.3116.0 Mobile Safari/537.36'
    },
    gzipEnabled: false,
    size: {
      raw: 0.08,
      message: '0.08kb',
      // if the api returned content length
      // if not RAPIP will give you an estimate
      'content-length': true
    },
    fetch: {
      name: 'Fetch',
      request: { raw: 448, message: '448ms' },
      parse: { raw: 4, message: '4ms' }
    },
    xhr: {
      name: 'XHR',
      request: { raw: 135, message: '135ms' },
      parse: { raw: 0, message: '0ms' }
    }
  }
}
  • api - api called.
  • emulation - Metadata about the emulator the test was run on.
  • gzipEnabled - If the code is encoded.
  • fetch - Request and parse metrics for a fetch request.
  • xhr - Request and parse metrics for a xhr request.

server(api, headers)

Start a server performance audit.

Parameters
  • api - Required. String url of the api you want to benchmark.
  • headers - Object of request headers you want to add to the api call.
Response
{ response: {
    request: { raw: '462', message: '462ms' },
    parse: { raw: '1', message: '1ms' },
    responseSize: { raw: '0.08', message: '0.08kb' },
    stringify: { raw: '8', message: '8ms' },
    gzipEnabled: false,
    api: 'https://httpbin.org/user-agent'
  }
}
  • request - How long in milliseconds the fetch request took.
  • parse - How long in milliseconds it took to parse the data.
  • responseSize - How large the response was in Kilobytes.
  • stringify - How long in milliseconds it took to stringify the parsed the data (can be interesting for serializing data for universial apps).
  • gzipEnabled - If the code is encoded.
  • api - api called.

Clientside framework

If you want to use the clientside performance framework you can use the command:

  npm start

Performance benchmarking

This will start a local instance of the framework which you can view in your browser with the url:

  # Default
  http://localhost:3000

You can then trigger a performance audit in the console but running the command:

performanceDemo()

This will console log the response of a demo request to: https://httpbin.org/user-agent with both Fetch and XHR.

If you want to try your own API call within the framework you can use either performanceTestApiWithFetch() or performanceTestApiWithXHR(). Both use the same interface:

performanceTestApiWithFetch(api, headers);
performanceTestApiWithXHR(api, headers);
  • api - Required. String url of the api you want to benchmark.
  • headers - Object of request headers you want to add to the api call.

Proxying API calls.

If you are performance testing an API from the perspective of a mobile phone you are constrained by the browser sandbox. If the API doesn't include CORS headers you will not be able to call it from your tests.

However to help this the client framework provides a (hopefully) transparent proxy. You can use it in the following way:

const { client } = require('rapip');

const PROXY = 'https://localhost:3000/api';
const API = 'https://httpbin.org/user-agent';
const HEADERS = {
  'x-rapip-api': API,
  'x-rapip-headers': "{'custom-headers':'wft'}",
}

async function runPerformanceTest() {
  const results = await client.performanceTestApi(PROXY, HEADERS);
  console.log(results);
  process.exit(0);
}

client.framework.listen(3000, () => {
  console.log('Listening on port 3000!');
  runPerformanceTest();
});

The call will now goto the proxy service and make a request to the URL set in the header x-rapip-api.

If you want the Proxy to forward on headers to the API, you can do this by giving the header x-rapip-headers a stringified JSON object.

The proxy should be completely transparent and any over headers it might have are removed from the request time. However if you do use the proxy your performance audit will include a proxy property which will include metadata about any processing time taken.

Response
{
  response: {
    api: 'https://httpbin.org/user-agent'
    emulation: {
      deviceEmulation: 'Nexus 5X',
      cpuThrottling: '4x slowdown',
      networkThrottling: '562.5ms RTT, 1.4Mbps down, 0.7Mbps up',
      userAgent: 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MRA58N) AppleWebKit/537.36(KHTML, like Gecko) Chrome/61.0.3116.0 Mobile Safari/537.36'
    },
    gzipEnabled: false,
    size: {
      raw: 0.08,
      message: '0.08kb',
      'content-length': true
    },
    fetch: {
      name: 'Fetch',
      request: { raw: 448, message: '448ms' },
      parse: { raw: 4, message: '4ms' },
      proxy: {
        requestTime : { raw: 445, message: '445ms' },
        proxyOverhead: { raw: 3, message: '3ms' },
        requestTimeWithCorrection: { raw: 448, message: '448ms' }
      }
    },
    xhr: {
      name: 'XHR',
      request: { raw: 135, message: '135ms' },
      parse: { raw: 0, message: '0ms' },
      proxy: {
        requestTime : { raw: 445, message: '445ms' },
        proxyOverhead: { raw: 3, message: '3ms' },
        requestTimeWithCorrection: { raw: 448, message: '448ms' }
      }
    }
  }
}

Examples

You can configure both server and clientside runners.

Clientside

With CORS example

Performance test API with CORS from a mobile device.

const { client } = require('rapip');

const API = 'https://httpbin.org/user-agent';

async function runPerformanceTest() {
  const results = await client.performanceTestApi(API);
  console.log(results);
  process.exit(0);
}

client.framework.listen(3000, () => {
  console.log('Listening on port 3000!');
  runPerformanceTest();
});

You can try this example with the command:

  npm run example:client

Without CORS example

If you want to Performance test API without CORS RAPIP offers a proxy that will add them for you.

const { client } = require('rapip');

const PROXY = 'https://localhost:3000/api';
const API = 'https://httpbin.org/user-agent';
const HEADERS = {
  'x-rapip-api': API
}

async function runPerformanceTest() {
  const results = await client.performanceTestApi(PROXY, HEADERS);
  console.log(results.response.fetch);
  process.exit(0);
}

client.framework.listen(3000, () => {
  console.log('Listening on port 3000!');
  runPerformanceTest();
});

You can try this example with the command:

  npm run example:client:proxy

Server

Performance test API on the server side.

const { server } = require('rapip');

const API = 'https://httpbin.org/user-agent';

async function getPerformanceMetrics() {
  const results = await server(`${API}`);
  console.log(results);
  process.exit(0);
}

getPerformanceMetrics();

You can try this example with the command:

  npm run example:server

TODO

  • add build and deploy steps
  • Clean the code
  • Add some tests
  • Make the code isomorphic
  • Move to use imports
  • Add more than gZip compression