How to test async REST API performance

Hi,

I would like to test async api performance. POST api call to api/createAsset starts the creation of the asset on the backend (that needs x time to be created).

After that GET api call api/getAsset checks if the server have finished the asset creation. While the asset is not yet created it return status “in_progress”, when the asset is created it return “finished” status.

I would like test that the api return status 200 and would like to measure performance (and set thresholds) for both GET api call and the time from the POST (start of the asset creation) to GET “finished” status (time that backend needed for the asset creation).

Can I do that with the framework and how would I go about it? I already have a custom script for this but would like to incorporate this into k6 framework.

Thanks!

Hi, welcome to the forum!

While k6 currently doesn’t support async/await, Promises, etc. (it is on the short to mid-term roadmap, though), it sounds like you don’t actually need them, and your workflow is entirely synchronous as far as the client is concerned, so you should be able to make those requests sequentially with the current version of k6.

That is, you could have something like:

import http from 'k6/http';
import { sleep } from 'k6';

const baseURL = 'http://...';
const createChecks = 10; // you could also plug this in from the environment with e.g. __ENV.CREATE_CHECKS

export default function () {
  let createRes = http.post(`${baseURL}/api/createAsset`, ...);
  let assetID = createRes.json()['id'];
  let asset;
  for (let i=0; i<createChecks; i++) {
    let getRes = http.get(`${baseURL}/api/getAsset/${assetID}`, ...);
    asset = getRes.json();
    if (asset['status'] === 'finished') {
      break;
    } else {
      sleep(5);
    }
  }
  // Do something with asset
}

For measuring the time between the first POST request until when the asset is created, you can measure the elapsed time with Date.now() (see this example) and record it with a custom Trend metric, so you can have statistics about it in the end-of-test summary.

Hope this helps!

1 Like

Thanks this was helpful. I still have some problems with threshold not being applied to the custom metric.

I define a custom metric at the start of the test:

let bakingTrend = new Trend('baking_time');

export let options = {
    thresholds: {
      bakingTrend: [{threshold: 'max<1', abortOnFail: true}]
    }
  };

And then add asset creation time when the asset finish:

bakingTrend.add(Date.now()-start);

I can see the baking_time metric in the report:

baking_time................: avg=979 min=979 med=979 max=979 p(90)=979 p(95)=979

But the threshold doesn’t fail as it should.

Hope you can give me some direction on how to implement this.

bakingTrend is the JS variable name, while baking_time is the name of the custom metric, and you need to set thresholds based on the metric name:

let thisDoesntMatter = new Trend('baking_time');

export let options = {
    thresholds: {
      baking_time: [{threshold: 'max<1', abortOnFail: true}]
    }
  };
1 Like