Performance Testing of a RESTful API using JMeter

Apache JMeter is open-source software that is popular for performance testing. This tool is designed to load test functional behavior and measure performance.

This article is about how to use JMeter for Performance Testing of a RESTful API. In this, we will learn how to configure JMeter and test a REST API to know how efficiently it works and how many concurrent users the server can handle.

For this, I created a RESTful API that lets you do the CRUD operation on a “Product.” A Product is a simple object that has a name, description, and price.

The API was created using three components of the MEAN stack –  NodeJs, Express and MongoDB.

The API methods are as follows:

Using JMeter, we will design the test that will

  • Use HTTP GET to retrieve a list of all items
  • Use HTTP POST to add a new item
  • Use HTTP PUT to update a newly added item
  • Use HTTP DELETE to delete the item added

Steps for Scripting a REST API in JMeter

As soon as you launch JMeter, you will see 2 elements: Test Plan and Workbench.

jmeter_1

1. This is the REST API. We will posting data as a JSON object, so we need to set a Content-Type header. For this, right click Test Plan and add Config Element → Http Header Manager and add “Content-Type.” Set value to “application/json.”

jmeter_2

2. Right click Test Plan. Select Add → Threads (Users) → Thread Group. Add the thread group.

  1. Set the name to “Item API Perf Test”
  2. Set the number of threads (users) to 10
  3. Set the Ramp-Up period (in seconds) to 10
  4. Set the Loop count to 10

So we will have 10 users executing the test plan 100 times. The Ramp-Up Period tells JMeter how long to delay before starting the next user.

jmeter_3

3. Right click Thread Group (Item API Perf Test) and add Config Elements → HTTP Request Defaults.

HTTP Request Defaults: This element lets you set default values that your HTTP Request controllers use. For example, if you are creating a Test Plan with 25 HTTP Request controllers and all of the requests are being sent to the same server, you could add a single HTTP Request Defaults element with the “Server Name or IP” field filled in.

So set the server name, port number, and the path to the resource.

  • Server Name: hostingserver.com (Server address where the RESTFul API is running)
  • Port Number: 8080
  • Path: /items
jmeter_4

4. Right click Thread Group (Item API Perf Test) and add Sampler → HTTP Request

Our first request will be to fetch all of the existing items. So set:

  • Name: Fetch All items
  • Method: GET
jmeter_5

5. For the second request to POST an item (aka create), let’s add another sampler. Right click Thread Group (Item API Perf Test) and add Sampler → HTTP Request

  • Name: Post an Item
  • Method: POST
  • Body Data: JSON Item Object
jmeter_6

Once the item is posted successfully, the response return will have a unique ID of the item.

{   "item": {   "__v": 0,  "name": "MacBook Pro 15-inch with Retina display ",
    	"description": "MacBook Pro 15-inch with Retina display",
   	 "price": 1699,  "priceUnit": "$", "_id": "5666907e6c5b4bb5525ba617"}
}

We need to extract that value so that we can use it in the subsequent requests to perform PUT (update) and DELETE operation.

For this, right click HTTP Request Sample (Post an Item) and add Post Processor → BSF PostProcessor. BSF PostProcessor provides read/write access to JMeter variables

Set the language to Javascript and add the following into the script:

var data = prev.getResponseDataAsString();
var object = JSON.parse(data);
vars.put("itemId", object.item._id);

What the above script is doing:

If you look into the “Script” section of the BSF Post Processor, you’ll see the following:

  • Script (variables: ctx, vars, props, prev, sampler…)
  • vars – stands for JMeterVariables. You can get or set variable values by using vars.
  • prev – shorthand to previous SampleResult. In this scenario, it contains the response of the POST request.
  • prev.getResponseDataAsString()  will extract the response as a string.

Use the JavaScript built-in function JSON.parse() to convert the string into a JavaScript object.

For the subsequent requests we need an ID, so we will create a variable called itemId:

vars.put("itemId", object.item._id);
jmeter_7

You can also use the BeanShell Post Processor to parse the JSON. We can easily invoke Java code in the Beanshell. For this scenario, here is simple way to extract the item ID.

jmeter_8

6. Now we will verify the insertion by retrieving the inserted item. For that, again right click Thread Group (Item API Perf Test) and dd Sampler → HTTP Request

  • Path: /items/${itenId}
  • Method: GET

By adding ${itemId} to the path, the request will be retrieving the single item.

jmeter_9

To verify the item inserted, add Response Assertion to the HTTP Request Sample (right click Assertions –> Response Assertion). Response Assertion lets you add pattern strings to be compared against various fields of the response.

For this, select the Text Response radio button for “Response Field to Test”. Set Pattern Matching Rules to “Contains” and add the item name in Patterns to Test.

jmeter_10

Please note that if the assertion fails, the test will stop and subsequent requests will be executed.

7. The next step is to update the item added. To do this, add another HTTP Request Sampler. Set the method to PUT and add the item’s new detail as Body Data. Also set the path to /items/${itemId}

jmeter_11

8. Now the last step is to delete the item added. For that, also add another HTTP Request Sampler. Set the method to Delete

jmeter_12

9. At last we can add different listeners like “View Results Tree” to conclude. To add, right click and select Listeners → View Results Tree.

In the View Results Tree, you can see the request and response data for each sample request.

jmeter_13

So the last step is to save and execute the test by pressing the green arrow on the top menu bar.

Here is how the results look in View Results in the Table, which shows a row for every sample request.

jmeter_14

In this way, we can do the performance as well as functional testing of a RESTful API.

By increasing the number of threads and loop count, we can increase the load on the server and measure various vitals of the server and API, such as CPU Utilization and average response time.

Sukhwinder Singh

Sukhwinder Singh

Senior Quality Assurance Engineer

Sukhwinder Singh is a Senior Quality Assurance Engineer at 3Pillar Global with over 3 years of experience in the field. His skills include manual testing, test automation, and performance testing. Prior to joining 3Pillar, he worked at CapeGemini and Hyperabad, and worked on projects related to the financial sector for a variety of clients. He loves exploring new tools and techniques related to performance testing and cloud computing.

14 Responses to “Performance Testing of a RESTful API using JMeter”
  1. amar on

    Hello,
    I have captured the json response as a string using:

    var data = prev.getResponseDataAsString();

    Now, I want to add some more items (hardcoded) to this response and send it back as a request. How could i do so.?

    Regards,
    Amar

    Please let me know

    Reply
    • Vishal on

      Hi Amar,

      Once you have received the response, you can extract the desired field from the response and then you can use this extracted value along with the hardcoded values in your next request.
      e.g.:
      Lets assume you have Email id in your response and you have extracted it in variable ’email’.
      Now in your next request you can use this variable alongwith other hardcoded values as below:

      NewEmail = ${email}+”AppendedValue”;

      Hope i answered your query.

      Reply
  2. Karan on

    Hi Sukhwinder,

    Please share the address of the web service for the above test.

    Regards,
    Karan

    Reply
  3. Apoorv Sharma on

    Nice article.

    Reply
  4. Paraminder Singh on

    For customer requirements, I will be following the steps mentioned in /performance-testing-of-a-restful-api-using-jmeter and I wil get back to you for more insights

    Reply
  5. Ashish on

    Helllo Sir,

    While I am trying to run my jmeter script, I can not able to redirect on home page after login.

    Facing below Error on response.

    if(“undefined”==typeof jQuery)throw new Error(“Bootstrap’s JavaScript requires jQuery”);+function(n){var t=n.fn.jquery.split(” “)[0].split(“.”);if(t[0]<2&&t[1]<9||1==t[0]&&9==t[1]&&t[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or

    Please suggest.

    Reply
  6. Divyashri Somayaji on

    Hello Sir, I am testing a website using jmeter. I recorded it using https script recorder.Many http request displayed and all parameters are displayed in the body data part instead of parameter part of http request. Why is that so? How to retrive them?why they are displayed in body data part? Please reply

    Reply
  7. Aakash Singh on

    Any method to assert the data, when response is in XML?

    Reply
  8. Yashwanth Nali on

    Hi there

    I’ve been trying to send an HTTP request (JSON file) using Jmeter. But I am facing HTTP 400 error.
    Tried using cache manager, cookie manager and provided a constant timer so that the requests can go periodically.
    Still, I am facing that 400 error issue. There no problem with the URL or the JSON file.
    Kindly help me in resolving the 400 Error.

    Reply
  9. Arasakuamri on

    I have created a test case for login & booking like ola/uber app. I need to pass a user authentication key for next call. For single thread it works. But if i increase thread count, authentication failed response showing. So i need to pass recently executed login authentication key for next call. How do i? Please help me out to execute the load test. I need a beanshell post procesor query to pass recently generated auth key.
    Note: Auth key will be generated in first call. Need to save and pass in next call header
    My beanshell script is.,
    import org.json.JSONObject;
    import org.json.JSONArray;
    String Response1 = prev.getResponseDataAsString();
    JSONObject StrResp1 = new JSONObject(Response1);
    JSONObject loginUser = StrResp1.getJSONArray(“detail”).getJSONObject(0).getJSONObject(“auth_details”);
    String authToken = loginUser.getString(“auth_key”);
    String userId = loginUser.getString(“user_id”);
    String userType = loginUser.getString(“user_type”);

    System.out.println(authToken);
    System.out.println(userId);
    System.out.println(userType);
    vars.put(“accessToken”,authToken);
    vars.put(“userid”,userId);
    vars.put(“usertype”,userType);

    Reply
  10. arun on

    Hi Sukhwinder,

    I have to run an rest api service called “Create Order” i can execute this POST service by giving body with only one user…To execute this service i need to run other 3 service ..How to run all this service together.

    Reply
  11. arun on

    i need to run an rest api service called create order …to execute that service i need to run other 3 services …how to run this service all together in jmeter

    Reply
  12. Ajitesh shukla on

    Great explanation, Sukhwinder

    Reply
  13. Shiva on

    can you please help to know how to generate performance graphs using jmeter

    Reply
Leave a Reply