JsonPath руководство для Mockarty
Содержание
- Что такое JsonPath
- Основной синтаксис
- Примеры использования
- Извлечение данных
- Переменные в ответах
- Store доступ
- Faker интеграция
- Сложные примеры
Совет: Примеры кода доступны для cURL, CLI и SDK-клиентов (Go, Python, Java). Смотрите Руководство по SDK для установки и настройки. Смотрите Руководство по CLI для командной утилиты.
URL-адреса в примерах: Во всех примерах используется
localhost:5770как адрес Mockarty по умолчанию. Если ваш экземпляр работает на удалённом сервере, заменитеlocalhost:5770на реальный адрес (например,https://mockarty.company.comилиhttp://192.168.1.50:5770). Подробнее — в разделе Полезные функции и советы.
Что такое JsonPath
JsonPath – это язык запросов для JSON-документов, аналогичный XPath для XML. Представьте его как систему “адресов” для данных внутри JSON – точно так же, как почтовый адрес помогает найти дом в городе, JsonPath-выражение помогает найти конкретное значение внутри JSON-документа.
Например, если у вас есть JSON-объект {"user": {"name": "John"}}, выражение $.user.name указывает прямо на "John". Символ $ означает “начать с корня документа”, а точки позволяют перемещаться вглубь вложенных объектов.
Когда это нужно? Всякий раз, когда вы хотите, чтобы мок вёл себя динамически, а не возвращал статичный ответ. Например, если клиент отправляет запрос с ID пользователя, вы можете с помощью JsonPath извлечь этот ID и включить его в ответ – и мок будет вести себя как настоящий сервис.
В Mockarty JsonPath используется для:
- Извлечения данных из входящих запросов
- Доступа к Store данным (Global, Chain, Mock)
- Генерации динамических ответов с переменными через Faker
- Проверки условий при мэтчинге моков
Куда записывать выражение
| Что нужно сделать | Куда поместить выражение | Пример |
|---|---|---|
| Прочитать поле текущего запроса | В поле ответа или правило extract |
$.req.email |
| Использовать данные запроса при следующем вызове | В extract.cStore или extract.gStore, затем в поле ответа |
Сохранить $.req.email, позже прочитать $.cS.email |
| Сгенерировать значение или вычислить результат | В поле ответа | $.fake.FirstName, $.sum($.req.price, 10) |
extract читает пути из входящего запроса. Faker и математические функции используйте в шаблонах ответа. Запись в Store может завершиться после текущего ответа, поэтому только что сохранённое значение читайте при следующем запросе.
Основной синтаксис
Базовые выражения
| Выражение | Описание | Пример |
|---|---|---|
$ |
Корень документа | $.user |
. |
Текущий узел | $.user.name |
[] |
Доступ по индексу/ключу | $.items[0], $.user['name'] |
* |
Все элементы | $.users[*].name |
.. |
Рекурсивный поиск | $..email |
?() |
Фильтр | $.items[?(@.price > 100)] |
Совет: Точка после
$необязательна –$req.fieldавтоматически нормализуется в$.req.field.
Специальные префиксы Mockarty
| Префикс | Описание | Пример |
|---|---|---|
$.req |
Тело запроса | $.req.userId |
$.reqHeader |
Заголовки запроса | $.reqHeader.Authorization[0] |
$.queryParams |
Query параметры HTTP | $.queryParams.limit |
$.mS |
Mock Store | $.mS.savedValue |
$.cS |
Chain Store | $.cS.sessionId |
$.gS |
Global Store | $.gS.counter |
$.pathParam |
Параметры URL-пути | $.pathParam.id для маршрута /api/users/:id |
$.fake |
Faker данные | $.fake.FirstName |
$.response |
Данные ответа (для webhook) | $.response.orderId |
$.namespace |
Текущий namespace | $.namespace |
Математические функции
| Функция | Описание | Пример |
|---|---|---|
$.increment(expr || default) |
Увеличить значение на 1 | $.increment($.gS.counter || 0) |
$.sum(expr1, expr2) |
Сумма двух значений | $.sum($.req.price, $.req.tax) |
$.multiply(expr1, expr2) |
Умножение двух значений | $.multiply($.req.quantity, $.req.price) |
$.subtract(expr1, expr2) |
Вычитание (expr1 - expr2) | $.subtract($.req.total, $.req.discount) |
$.divide(expr1, expr2) |
Деление (expr1 / expr2; деление на ноль даёт 0) | $.divide($.req.total, $.req.count) |
$.modulo(expr1, expr2) |
Остаток от деления expr1 / expr2 | $.modulo($.req.index, 2) |
$.length(expr) |
Размер значения: число элементов массива, число ключей объекта или число рун строки | $.length($.req.items) |
Аргументами могут быть:
- Числовые литералы:
$.sum(10, 20) - JsonPath выражения:
$.sum($.req.a, $.req.b) - Store ссылки:
$.sum($.gS.total, $.req.amount) - Выражения с default:
$.increment($.gS.counter || 0)– если значение отсутствует, используется0
Строковые функции
Преобразуют одно значение, полученное из любого вложенного выражения (поле запроса, faker, store или другая строковая функция).
| Функция | Описание | Пример |
|---|---|---|
$.upper(expr) |
Привести к верхнему регистру | $.upper($.req.code) |
$.lower(expr) |
Привести к нижнему регистру | $.lower($.fake.Email) |
$.trim(expr) |
Убрать пробелы в начале и конце | $.trim($.req.name) |
$.replace(expr, old, new) |
Заменить все вхождения old на new |
$.replace($.req.phone, "-", "") |
$.substring(expr, start[, end]) |
Срез по индексу символа (end необязателен) |
$.substring($.req.code, 0, 4) |
$.default(expr, fallback) |
Использовать fallback, если первое значение пустое |
$.default($.req.name, "guest") |
$.base64encode(expr) |
Закодировать значение в стандартный base64 | $.base64encode($.req.creds) |
$.base64decode(expr) |
Декодировать стандартный base64 (невалидный вход — как есть) | $.base64decode($.req.token) |
$.urlencode(expr) |
URL-кодирование (query-эскейпинг) | $.urlencode($.req.q) |
$.urldecode(expr) |
URL-декодирование | $.urldecode($.req.q) |
- Каждая функция возвращает строку, поэтому их можно вкладывать:
$.upper($.trim($.req.code)). - Строковые литералы указываются в кавычках (
"..."или'...'); всё, что начинается с$., сначала резолвится — можно передавать поля запроса, faker или значения store как аргументы. - Если выражение ничего не вернуло, результат — пустая строка (именно это проверяет
$.default). $.substringсчитает символы, а не байты, и обрезает выход за границы — поэтому не падает на коротком значении.
Функция времени
$.now(...) возвращает текущее время с необязательным относительным сдвигом и форматом вывода. В отличие от $.fake-полей дат (случайных), $.now — это реальное «сейчас»: идеально для срока действия токена, меток created/updatedAt или даты на фиксированном расстоянии от сегодня.
| Форма | Результат |
|---|---|
$.now() |
Текущее время, RFC3339 (UTC), напр. 2026-07-25T14:30:45Z |
$.now(30d) |
Сейчас + 30 дней, RFC3339 |
$.now(-1h) |
Сейчас − 1 час, RFC3339 |
$.now(0, date) |
Сегодня как 2026-07-25 |
$.now(7d, unix) |
(сейчас + 7 дней) в epoch-секундах |
$.now(0, "15:04") |
Сейчас с произвольным Go-layout |
- Сдвиг: единицы
s(секунды),m(минуты),h(часы),d(дни),w(недели); можно комбинировать (1d12h) и ставить-для движения в прошлое. Пусто или0— ровно сейчас. - Формат (пресеты):
rfc3339(по умолчанию),rfc3339nano,date,datetime,time,unix,unixmilli. Любое другое значение трактуется как сырой Go-layout (напр.2006-01-02).
Примеры использования
Простое извлечение
JSON документ:
{
"user": {
"id": 123,
"name": "John Doe",
"email": "john@example.com"
}
}
JsonPath выражения:
$.user.id // → 123
$.user.name // → "John Doe"
$.user.email // → "john@example.com"
$['user']['id'] // → 123 (альтернативный синтаксис)
Работа с массивами
JSON документ:
{
"users": [
{"id": 1, "name": "John", "active": true},
{"id": 2, "name": "Jane", "active": false},
{"id": 3, "name": "Bob", "active": true}
]
}
JsonPath выражения:
$.users[0] // → {"id": 1, "name": "John", "active": true}
$.users[0].name // → "John"
$.users[-1] // → {"id": 3, "name": "Bob", "active": true} (последний)
$.users[*].name // → ["John", "Jane", "Bob"]
$.users[*].id // → [1, 2, 3]
Фильтрация
// Активные пользователи
$.users[?(@.active == true)]
// → [{"id": 1, "name": "John", "active": true}, {"id": 3, "name": "Bob", "active": true}]
// Имена активных пользователей
$.users[?(@.active == true)].name
// → ["John", "Bob"]
// Пользователи с ID больше 1
$.users[?(@.id > 1)]
// Пользователи с именем содержащим "J"
$.users[?(@.name =~ /.*J.*/i)]
Рекурсивный поиск
JSON документ:
{
"company": {
"departments": [
{
"name": "IT",
"employees": [
{"name": "John", "email": "john@company.com"},
{"name": "Jane", "email": "jane@company.com"}
]
},
{
"name": "HR",
"head": {"name": "Bob", "email": "bob@company.com"}
}
]
}
}
JsonPath выражения:
$..email // → ["john@company.com", "jane@company.com", "bob@company.com"]
$..name // → ["IT", "John", "Jane", "HR", "Bob"]
Извлечение данных
Извлечение из запроса
HTTP запрос:
POST /api/users
{
"user": {
"name": "John Doe",
"email": "john@example.com",
"preferences": {
"theme": "dark",
"notifications": true
}
}
}
Извлечение в Mock:
{
"extract": {
"mStore": {
"userName": "$.req.user.name",
"userEmail": "$.req.user.email",
"userTheme": "$.req.user.preferences.theme"
},
"gStore": {
"lastUserName": "$.req.user.name"
}
}
}
Извлечение заголовков
HTTP запрос:
POST /api/data
Authorization: Bearer abc123token
Content-Type: application/json
X-User-ID: user-456
Извлечение:
{
"extract": {
"mStore": {
"authToken": "$.headers.Authorization",
"contentType": "$.headers['Content-Type']"
}
}
}
В правиле extract используйте $.headers. Заголовок с одним значением представлен строкой, с несколькими — массивом; чтобы взять первое значение массива, добавьте [0]. В шаблонах ответа для заголовков используется другой префикс — $.reqHeader из таблицы выше.
Извлечение query параметров
Для query строки (?limit=10&offset=20) используйте $.queryParams:
Запрос: GET /api/users?limit=10&offset=20&sort=name
{
"response": {
"payload": {
"limit": "$.queryParams.limit",
"offset": "$.queryParams.offset",
"sort": "$.queryParams.sort"
}
}
}
Можно использовать query параметры в условиях:
{
"conditions": [
{
"queryParam": "status",
"assertAction": "equals",
"value": "active"
}
]
}
Сложные условия
{
"conditions": [
{
"path": "$.order.items[*].price",
"assertAction": "contains",
"value": 100
},
{
"path": "$.order.items[?(@.category == 'electronics')].price",
"assertAction": "matches",
"value": "^[1-9]\\d{2,}$"
}
]
}
Операторы условий (assertAction)
| Оператор | Совпадает, когда значение… | value |
|---|---|---|
equals |
равно value |
ожидаемое значение |
not_equals |
не равно value |
значение для исключения |
contains |
содержит value (подстрока / элемент массива); для числа или логического значения — точное равенство, 100 не содержит 10 |
подстрока или элемент |
not_contains |
не содержит value (для числа или логического значения — не равно ему) |
подстрока или элемент |
starts_with |
начинается с value |
префикс |
ends_with |
заканчивается на value |
суффикс |
is_number |
является числом (целым или дробным) | — (игнорируется) |
num_digits |
состоит только из цифр, и их ровно value |
количество цифр, напр. 6 для одноразового кода |
one_of |
равно одному из списка | список ["open","closed"] или строка через запятую "open, closed" |
matches |
совпадает с регулярным выражением value |
regex-шаблон |
notEmpty / empty |
непустое / пустое | — (игнорируется) |
any |
совпадает всегда (проверка наличия) | — (игнорируется) |
Операторы starts_with, ends_with, is_number, num_digits и one_of
покрывают частые случаи без регулярных выражений — например, шестизначный
код подтверждения:
{
"conditions": [
{ "path": "$.otp", "assertAction": "num_digits", "value": 6 }
]
}
Переменные в ответах
Использование извлеченных данных
{
"response": {
"statusCode": 201,
"payload": {
"id": "$.fake.UUIDDigit",
"name": "$.req.user.name",
"email": "$.req.user.email",
"welcomeMessage": "Hello $.req.user.name!",
"timestamp": "$.fake.RFC3339",
"preferences": "$.req.user.preferences"
}
}
}
Объединение значений
{
"response": {
"payload": {
"fullName": "$.req.firstName $.req.lastName",
"displayName": "Mr. $.req.lastName",
"loginUrl": "https://example.com/login?user=$.req.userId"
}
}
}
Store доступ
Полное руководство по системам хранилищ см. в документации Store Systems.
Global Store
Через extract.gStore можно сохранить поле входящего запроса. Например, тело запроса содержит {"userId":"u-42"}:
{
"extract": {
"gStore": {"lastActiveUser": "$.req.userId"}
}
}
Другой мок в том же пространстве имён сможет прочитать сохранённое значение при следующем вызове:
{
"response": {
"payload": {"lastActiveUser": "$.gS.lastActiveUser"}
}
}
Chain Store
Укажите одинаковый chainId у моков, которым нужны общие данные цепочки. Первый мок сохраняет поля запроса, а в своём ответе использует данные текущего запроса:
{
"chainId": "user-registration",
"extract": {
"cStore": {
"userId": "$.req.userId",
"email": "$.req.email"
}
},
"response": {
"payload": {"userId": "$.req.userId", "status": "registered"}
}
}
Следующий мок этой цепочки читает сохранённые значения:
{
"chainId": "user-registration",
"response": {
"payload": {"userId": "$.cS.userId", "email": "$.cS.email"}
}
}
Области видимости и срок хранения описаны в руководстве по Store.
Faker интеграция
Полный список всех доступных Faker-функций см. в Справочнике Faker.
Основные Faker функции
{
"response": {
"payload": {
"id": "$.fake.UUID",
"name": "$.fake.FirstName",
"lastName": "$.fake.LastName",
"email": "$.fake.Email",
"phone": "$.fake.Phone",
"address": "$.fake.Address",
"city": "$.fake.City",
"country": "$.fake.Country",
"company": "$.fake.Company",
"jobTitle": "$.fake.JobTitle",
"website": "$.fake.URL",
"avatar": "$.fake.URL",
"birthDate": "$.fake.Date",
"timestamp": "$.fake.RFC3339",
"unixTime": "$.fake.UnixTime"
}
}
}
Числовые Faker функции
{
"response": {
"payload": {
"randomInt": "$.fake.Int",
"positiveInt": "$.fake.PositiveInt",
"negativeInt": "$.fake.NegativeInt",
"float": "$.fake.Float",
"price": "$.fake.Price",
"latitude": "$.fake.Latitude",
"longitude": "$.fake.Longitude",
"boolean": "$.fake.Bool"
}
}
}
Локализованные данные
{
"response": {
"payload": {
"russianName": "$.fake.RussianFirstNameMale",
"russianSurname": "$.fake.RussianLastNameMale",
"chineseName": "$.fake.FirstName",
"germanName": "$.fake.FirstName",
"sentence": "$.fake.Sentence",
"paragraph": "$.fake.Paragraph",
"word": "$.fake.Word"
}
}
}
Математические операции
Подробные примеры
Счётчик с увеличением
Поместите $.increment в шаблон ответа. Функция увеличивает счётчик в Global Store и возвращает новое значение:
{
"http": {"route": "/api/counter", "httpMethod": "GET"},
"response": {
"payload": {"visits": "$.increment($.gS.visitCount || 0)"}
}
}
Первый вызов возвращает 1, каждый следующий увеличивает счётчик один раз. || 0 задаёт начальное значение. Если нужен один шаг на запрос, используйте выражение только один раз в ответе.
Суммирование и умножение
{
"response": {
"payload": {
"subtotal": "$.req.price",
"tax": "$.multiply($.req.price, 0.2)",
"total": "$.sum($.req.price, $.multiply($.req.price, 0.2))",
"discount": "$.subtract($.req.price, 10)"
}
}
}
Важно: Математические функции работают с числовыми значениями. Строки автоматически преобразуются в числа. Если преобразование невозможно, используется значение 0.
Строковая интерполяция
JsonPath выражения можно встраивать прямо в текстовые строки:
{
"response": {
"payload": {
"greeting": "Hello $.req.name, welcome!",
"link": "https://example.com/users/$.req.id/profile",
"message": "Order #$.fake.UUIDDigit confirmed for $.req.email"
}
}
}
Все выражения $.xxx внутри строк будут автоматически заменены на соответствующие значения.
Сложные примеры
В каждом примере ниже показана одна задача. Добавляйте только те поля, которые нужны вашему клиенту.
Динамический счётчик
Для счётчика запросов используйте пример с увеличением. Одно выражение $.increment(...) обновляет сохранённое значение и возвращает его в ответе.
Цепочка для данных пользователя
Для двух шагов используйте пример Chain Store: первый мок сохраняет userId и email из запроса через extract.cStore, а следующий читает их через $.cS.userId и $.cS.email. Генерируйте новое значение в ответе только тогда, когда оно не должно совпадать с отдельно сохранённым значением.
Обработка заказа
Пусть тело запроса содержит {"orderId":"o-17","quantity":2,"unitPrice":10}. Мок возвращает номер заказа и рассчитанную сумму, а номер сохраняет для последующих запросов:
{
"id": "process-order",
"http": {"route": "/api/orders", "httpMethod": "POST"},
"response": {
"payload": {
"orderId": "$.req.orderId",
"total": "$.multiply($.req.quantity, $.req.unitPrice)"
}
},
"extract": {
"gStore": {"lastOrderId": "$.req.orderId"}
}
}
Ответ с данными из Store
При следующем запросе можно прочитать сохранённый номер заказа. $.now() добавит время формирования ответа:
{
"id": "analytics-report",
"http": {"route": "/api/analytics/report", "httpMethod": "GET"},
"response": {
"payload": {
"lastOrderId": "$.gS.lastOrderId",
"generatedAt": "$.now()"
}
}
}
Утилиты для работы с JsonPath

Тестирование JsonPath
Mockarty позволяет проверить JsonPath-выражение на произвольном JSON, не создавая мок: в админ-панели через Utils → Testers → JsonPath либо по REST. Оба пути вычисляют выражение тем же экстрактором, что и ваши моки, — увиденный здесь результат совпадёт с тем, что даст условие мока или $.-подстановка.
В интерфейсе: введите выражение, вставьте JSON-документ — результат появляется по мере ввода. Невалидный документ, неверное выражение и выражение без совпадений сообщают о себе прямо над полем.
Endpoint: POST /api/v1/utils/extract-jpath
Тело запроса:
| Поле | Тип | Описание |
|---|---|---|
jpath |
string | JsonPath-выражение для вычисления |
from |
object | JSON-документ, к которому применяется выражение |
Пример cURL:
curl -X POST http://localhost:5770/api/v1/utils/extract-jpath \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MOCKARTY_API_TOKEN" \
-d '{
"jpath": "$.users[*].email",
"from": {
"users": [
{"name": "John", "email": "john@example.com"},
{"name": "Jane", "email": "jane@example.com"}
]
}
}'
Ответ:
{
"extract": ["john@example.com", "jane@example.com"]
}
Endpoint намеренно не покрыт SDK — это отладочный helper, а не часть автоматизационного API. SDK (Go/Python/Java) и CLI не содержат специальной обёртки; используйте обычный HTTP POST из вашего языка или Utils → Testers → JsonPath в админ-панели.
Отладка выражений
Пример отладочного мока:
{
"id": "debug-jsonpath",
"http": {
"route": "/debug/jsonpath"
},
"response": {
"payload": {
"request": "$.req",
"headers": "$.reqHeader",
"mockStore": "$.mS",
"chainStore": "$.cS",
"globalStore": "$.gS",
"fakeData": {
"uuid": "$.fake.UUID",
"name": "$.fake.FirstName",
"email": "$.fake.Email"
}
}
}
}
Известные ограничения
При использовании JsonPath-выражений внутри строковых значений JSON (не как самостоятельное значение поля) действуют следующие ограничения из-за regex-движка интерполяции:
| Возможность | Самостоятельное значение | Внутри строки |
|---|---|---|
Простые пути $.req.user.id |
Работает | Работает |
Индекс массива $.req.items[0] |
Работает | Работает |
Отрицательный индекс $.req.items[-1] |
Работает | НЕ работает |
Wildcard $.req.items[*].name |
Работает | НЕ работает |
Рекурсивный спуск $..email |
Работает | НЕ работает |
Фильтр $.items[?(@.price>100)] |
Работает | НЕ работает |
Fallback-синтаксис || работает только внутри аргументов математических функций:
- Работает:
$.increment($.gS.counter || 0) - НЕ работает как самостоятельное выражение:
$.req.userId || "default"
Неразрешённые выражения возвращают строку ошибки вида "Error: JSONPath '$.req.missing' not found" как в JSON-, так и в XML-ответах. Это касается как самостоятельных значений $.xxx, так и выражений $.xxx, встроенных в строки. Используйте синтаксис || default внутри математических функций (например, $.increment($.gS.counter || 0)), чтобы корректно обрабатывать отсутствующие значения.
Глубина рекурсии ограничена 15 уровнями вложенности JSON-объектов.
Лучшие практики
-
Используйте осмысленные имена в Store:
"extract": { "cStore": { "userId": "$.req.id", "userEmail": "$.req.email", "sessionStartTime": "$.fake.RFC3339" } } -
Используйте
||fallback в математических функциях для обработки отсутствующих значений:$.increment($.gS.counter || 0) $.sum($.gS.price || 0, $.req.tax)Примечание: Синтаксис
||работает только внутри аргументов математических функций ($.increment,$.sum,$.multiply,$.subtract). Он НЕ работает как самостоятельное выражение вроде$.req.user.id || "default-id". -
Используйте фильтры для сложной логики:
$.orders[?(@.status == 'completed' && @.amount > 100)] -
Комбинируйте статические и динамические данные:
{ "message": "Hello $.req.name! Your order #$.fake.UUIDDigit is confirmed", "timestamp": "$.fake.RFC3339" }
XML поддержка
JsonPath выражения также работают внутри XML ответов (SOAP моки):
{
"response": {
"payload": "<GetUserResponse><UserId>$.req.id</UserId><Name>$.fake.FirstName</Name><Email>$.fake.Email</Email></GetUserResponse>"
}
}
Mockarty автоматически экранирует спецсимволы XML (<, >, &, ", ') при подстановке значений в XML строки. Также нормализует пробелы в namespace-ах и атрибутах.
Go Template режим
Помимо JsonPath, Mockarty поддерживает Go Template синтаксис для файловых шаблонов. Загрузите шаблон из файла через поле templateFile:
{
"response": {
"templateFile": "my-template.json"
}
}
Доступные функции внутри Go Template:
| Функция | Описание | Пример |
|---|---|---|
req |
Данные запроса (без аргументов, возвращает объект запроса) | {{(req).user.name}} |
reqHeader |
Данные заголовка (без аргументов, возвращает map заголовков) | {{index (reqHeader) "Authorization"}} |
fake |
Faker данные (без аргументов, возвращает объект faker) | {{(fake).FirstName}} |
mS |
Mock Store (без аргументов, возвращает map хранилища) | {{index (mS) "key"}} |
cS |
Chain Store (без аргументов, возвращает map хранилища) | {{index (cS) "key"}} |
gS |
Global Store (без аргументов, возвращает map хранилища) | {{index (gS) "key"}} |
asJson |
Преобразование в JSON | {{asJson .Request}} |
Важно: Go Template и JsonPath – два разных режима. JsonPath работает в полях
payload(JSON), Go Template работает вtemplateFile.
Используйте это руководство для создания мощных динамических моков с JsonPath!
Смотрите также
- Справочник Faker-функций – все доступные функции для генерации тестовых данных
- Системы хранилищ (Store) – Global, Chain и Mock хранилища для моков с состоянием
- Справочник API – полный REST API, включая endpoint для тестирования JsonPath
- Руководство по веб-интерфейсу – визуальный конструктор моков с поддержкой JsonPath
- Быстрый старт – начните работу с первым динамическим моком