If you are testing modern REST APIs -- and in 2024, that is most projects -- the JSON Extractor is your best friend. It is cleaner than regex for JSON responses, less error-prone, and easier to read. While regex says "find text between these boundaries," the JSON Extractor says "navigate to this path in the JSON structure." It uses JSONPath, which is like XPath but for JSON.
| Field | Purpose | Example |
|---|---|---|
| Names of created variables | Variable name(s) to store results | auth_token;user_id (semicolon-separated for multiple) |
| JSON Path Expressions | JSONPath query to locate the value | $.token;$.user.id (semicolon-separated) |
| Match No. | Which match to use (same as regex) | 1 (first match) |
| Compute concatenation var | Creates var_ALL with all matches concatenated | Check if you need all values joined |
| Default Values | Fallback if path not found | NOT_FOUND;NOT_FOUND (semicolon-separated) |
JSONPath is intuitive once you understand the notation. The dollar sign $ represents the root of the JSON document. Dots navigate into objects. Square brackets access arrays. Let me walk through real examples from actual API responses.
{
"status": "success",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U",
"user": {
"id": 42,
"name": "Priya Sharma",
"email": "priya@example.com",
"roles": ["admin", "tester"],
"settings": {
"theme": "dark",
"notifications": true
}
},
"orders": [
{ "orderId": "ORD-001", "total": 1500, "status": "delivered" },
{ "orderId": "ORD-002", "total": 3200, "status": "pending" },
{ "orderId": "ORD-003", "total": 750, "status": "delivered" }
]
}# Basic property access:
$.token -> eyJhbGci... (the full JWT)
$.status -> success
$.user.id -> 42
$.user.name -> Priya Sharma
$.user.email -> priya@example.com
# Nested object:
$.user.settings.theme -> dark
$.user.settings.notifications -> true
# Array access by index (0-based):
$.user.roles[0] -> admin
$.user.roles[1] -> tester
$.orders[0].orderId -> ORD-001
$.orders[1].total -> 3200
# Array wildcard (all elements):
$.orders[*].orderId -> ORD-001, ORD-002, ORD-003
$.orders[*].status -> delivered, pending, delivered
# Array filter (conditional):
$.orders[?(@.status=="delivered")].orderId -> ORD-001, ORD-003
$.orders[?(@.total>1000)].orderId -> ORD-001, ORD-002
# Last element:
$.orders[-1].orderId -> ORD-003
# Recursive descent (find anywhere in tree):
$..orderId -> ORD-001, ORD-002, ORD-003
$..email -> priya@example.comA huge advantage of the JSON Extractor over regex is that you can extract multiple values in a single extractor. Use semicolons to separate variable names, JSONPath expressions, and default values. This keeps your test plan cleaner.
# In one JSON Extractor:
# Names of created variables: auth_token;user_id;user_name
# JSON Path Expressions: $.token;$.user.id;$.user.name
# Default Values: NO_TOKEN;NO_ID;NO_NAME
# This creates three variables in one step:
# ${auth_token} = eyJhbGci...
# ${user_id} = 42
# ${user_name} = Priya Sharma
# Without this, you would need three separate JSON Extractors!When your JSONPath matches multiple values (like $.orders[*].orderId returning three IDs), Match No. works the same as in the regex extractor: 1 for first, 0 for random, -1 for all. With -1, it creates the same numbered variables pattern.
# JSONPath: $.orders[*].orderId
# Match No.: -1
# Variable: order_id
# Creates:
# ${order_id_1} = ORD-001
# ${order_id_2} = ORD-002
# ${order_id_3} = ORD-003
# ${order_id_matchNr} = 3
# To use a random order in a subsequent request:
# ${__V(order_id_${__Random(1,${order_id_matchNr})})}
# To iterate through all orders, use ForEach Controller:
# Input Variable Prefix: order_id
# Output Variable Name: current_order
# Then inside the loop, use ${current_order}Q: When would you use a Regular Expression Extractor instead of a JSON Extractor for a JSON response?
A: Even with JSON responses, the Regular Expression Extractor is better when: (1) The response is not valid JSON but contains JSON fragments, (2) You need to extract a value from response headers rather than the body, (3) The value spans across a non-standard format like JSONP wrapped in a callback function, (4) You need to extract a substring from within a JSON value (like a specific part of a URL stored as a JSON string), or (5) The JSON library in your JMeter version has a bug with certain edge cases. But for standard REST APIs, always prefer the JSON Extractor.
Use the website jsonpath.com to test your JSONPath expressions before putting them into JMeter. Paste your JSON response, write the expression, and see the result immediately. This saves a lot of run-debug-fix cycles.
Key Point: The JSON Extractor uses JSONPath ($.path.to.value) to navigate JSON responses. It handles nested objects, arrays, and filters natively and is always preferred over regex for valid JSON responses.