// Article - How to extract values using a JSON Path Expression from the Response Body in Rungutan

Written April 20, 2021

Intro

In case you’re searching for tutorials on how to use JSON Path Expression to extract values in your API load test scenarios, you’ve come to the right place. In this article, Rungutan team will show you step by step how to do that. Why is this important? Because in this way you can easily extract values from the JSON response body and reuse them in your workflow!

Let’s get started!

What is JSON Path Expression?

JsonPath expressions always refer to a JSON structure in the same way as XPath expression are used in combination with an XML document. The "root member object" in JsonPath is always referred to as $ regardless if it is an object or array.

JsonPath expressions, in Rungutan, uses the dot–notation:


$.store.book[0].title
                                            

The leading $ represents the root object or array and can be omitted. For example, $.foo.bar and foo.bar are the same, and so are $[0].status and [0].status.

Other syntax elements are described below.

Expression Description

$

The root object or array.

.property

Selects the specified property in a parent object.

['property']

Selects the specified property in a parent object. Be sure to put single quotes around the property name.

Tip: Use this notation if the property name contains special characters such as spaces, or begins with a character other than A..Za..z_.

[n]

Selects the n-th element from an array. Indexes are 0-based.

..property

Recursive descent: Searches for the specified property name recursively and returns an array of all values with this property name. Rungutan always picks a random value from this list to extract.

*

Wildcard selects all elements in an object or an array, regardless of their names or indexes. For example, address.* means all properties of the address object, and book[*] means all items of the book array.

[start:end]
[start:]

Selects array elements from the start index and up to, but not including, end index. If end is omitted, selects all elements from start until the end of the array. Rungutan always picks a random value from this list to extract.

[:n]

Selects the first n elements of the array. Rungutan always picks a random value from this list to extract.

[-n:]

Selects the last n elements of the array. Rungutan always picks a random value from this list to extract.

[?(expression)]

Selects all elements in an object or array that match the specified filter. Rungutan always picks a random value from this list to extract.

[(expression)]

Script expressions can be used instead of explicit property names or indexes. An example is [(@.length-1)] which selects the last item in an array. Here, length refers to the length of the current array rather than a JSON field named length.

@

Used in filter expressions to refer to the current node being processed.

Detailed examples

Let's consider the following JSON response:


{
  "store": {
    "book": [
      {
        "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": 8.95
      },
      {
        "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": 8.99
      },
      {
        "category": "fiction",
        "author": "J.R.R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": 22.99
      }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  },
  "expensive": 10
}
                                            
Expression Meaning
$.store.bicycle.color

The color of the bicycle in the store.

Result: red

$.store..price
$..price

The prices of all items in the store.

Result: [8.95, 8.99, 22.99, 19.95]

$.store.book[*].author
$..book[*].author

All authors of books in the store.

$..book[*].title

The titles of all books in the store.

Result:
[ "Sayings of the Century", "Moby Dick", "The Lord of the Rings" ]

$..book[0].category

The category of the first book.

Result:reference

$..book[0].title

The title of the first book.

Result: Sayings of the Century

$..book[0,1].title
$..book[:2].title

The titles of the first two books.

Result: [Sayings of the Century, Moby Dick]

$..book[-1:].title
$..book[(@.length-1)].title

The title of the last book.

Result: [The Lord of the Rings]

$..book[?(@.author=='J.R.R. Tolkien')].title

The titles of all books by J.R.R. Tolkien (exact match, case-sensitive).

Result: [The Lord of the Rings]

$..book[?(@.isbn)].title

The title of all books that have the isbn property.

$..book[?(@.price < 10)].title

The titel of all books with price smaller than 10.

Sample workflows

The JSON Path Expression key is available as part of the extract parameter under any and all workflow steps.

Since the extract key is an array, you can therefore to extract as many values as you need, but just make sure that you don't duplicate the name of the parameter that you save it as!

Yes, the key alternative is pretty similar, but it does not offer the same in-depth functionality that the json_path_expression does!

Also, it's good to keep in mind that they key functionality, although available to be used in the response body as well, has been designed to work specifically with extracting values from the headers!

Here's a sample worfklow which uses the json_path_expression field:


{
    "num_clients": 30,
    "run_time": 30,
    "threads_per_region": 1,
    "workflow": [
        {
            "path": "https://example.com/v1/api/tests/list",
            "method": "POST",
            "headers": {
                "Content-Type": "application/json",
                "X-Api-Key": "${vault.api_key}"
            },
            "extract": [
                {
                    "parameter_name": "test_id",
                    "location": "body",
                    "json_path_expression": "Tests[*].test_id"
                }
            ],
            "data": "{\"team_id\":\"rungutan\"}",
            "files": []
        },
        {
            "path": "https://example.com/v1/api/tests/get",
            "method": "POST",
            "headers": {
                "Content-Type": "application/json",
                "X-Api-Key": "${vault.api_key}"
            },
            "data": "{\"team_id\":\"rungutan\", \"test_id\":\"${test_id}\"}",
            "extract": [],
            "files": []
        }
    ],
    "test_region": [
        "eu-west-1",
        "eu-west-2"
    ],
    "test_name": "List all tests, extract a random test_id using path expression and fetches its details"
}
                                            

First workflow step:

  1. Hit the /v1/api/tests/list path with POST
  2. Inject the X-Api-Key header with the relevant Vault key
  3. Extract a random test_id key from the Tests array in the JSON response and STORE it in the variable named test_id

Second workflow step:

  1. Hit the /v1/api/tests/get path with POST
  2. Inject the X-Api-Key header with the relevant Vault key
  3. Set the payload as {“team_id”:”rungutan”, “test_id”:”${test_id}”} by referencing the value of the variable that we extracted in the previous step

Easy enough, right ?

Final thoughts

This tutorial offered you a glimpse of how powerful Rungutan is and how easy it is to simply extract values from the response body and reuse them in your workflow!


Share on LinkedIn

Share on Facebook

Share on Twitter