Урок курса

Данные между узлами: items, JSON и expressions

n8n с нуля: автоматизация заявок с AI за вечер

В прошлом уроке вы собрали workflow из трёх узлов и запустили его. Edit Fields создал поля, Manual Trigger дал старт, панель Output показала результат. Теперь разберёмся, в каком именно формате эти данные существуют внутри n8n — и как их читать, прежде чем работать с ними дальше.

Item как единица данных: структура и JSON-представление

В n8n данные между узлами не передаются как одна запись или одна таблица целиком. Вместо этого узел получает на вход массив items и возвращает массив items на выход. Каждый item — это самостоятельный объект, который несёт свои данные независимо от соседних.

Каждый item устроен одинаково: у него есть поле json — словарь произвольных ключей и значений — и опциональное поле binary для файлов и вложений. В большинстве сценариев работают именно с json.

Представьте, что вы обрабатываете список заявок. Каждая заявка — отдельный item. Если в массиве три заявки, узел получит три items и вернёт три items (или больше/меньше — зависит от логики узла). Это важно: один запуск workflow может обрабатывать не одну запись, а сразу несколько параллельно.

Как читать данные в панели Output

Когда узел отработал, в панели Output справа появляются его результаты. Там есть два режима просмотра:

  • Table — удобная таблица, где каждый item — строка, а поля — колонки. Хорошо подходит для быстрого взгляда на данные.
  • JSON — сырое дерево данных, где видно точные имена ключей, вложенность объектов и типы значений (строка, число, булево, null).

Режим Table — для быстрой проверки. Режим JSON — для диагностики: именно здесь видно, как именно называется поле, есть ли у него вложенные объекты, какой у него тип. Если expression не работает как ожидалось, первый шаг — переключиться в JSON и проверить точное имя ключа.

Вот как выглядит типичный item в JSON-представлении:

{
  "json": {
    "firstName": "Анна",
    "lastName": "Смирнова",
    "priority": "Срочно",
    "amount": 4200
  }
}

Здесь json — это обёртка, которую n8n добавляет к каждому item. Внутри неё лежат реальные данные: четыре поля с конкретными значениями разных типов — строки и число.

Когда в режиме Table видно четыре колонки (firstName, lastName, priority, amount), это ровно те же данные — просто в другом представлении. Ни одно поле не потерялось и не добавилось; изменился только способ отображения.

Понимание этой структуры — отправная точка для всего, что будет дальше: чтобы обратиться к полю в expression или передать его в следующий узел, нужно точно знать, как это поле называется в JSON.

Панель Output узла Edit Fields в режиме JSON

Панель Output узла Edit Fields в режиме JSON.

Expression: синтаксис и обращение к полям текущего item

Когда нужно не просто передать item дальше, а взять конкретное поле и подставить его значение куда-то — в имя файла, в текст сообщения, в параметр запроса — используют expression. Expression — это шаблонная строка, которая вычисляется в момент запуска узла. Синтаксис простой: всё, что написано между {{ и }}, n8n интерпретирует как JavaScript-выражение, а не как текст.

Доступ к полям текущего item осуществляется через объект $json. Если item выглядит так:

{
  "json": {
    "firstName": "Анна",
    "priority": "Срочно",
    "amount": 4200
  }
}

то обратиться к полю priority можно так:

{{ $json.priority }}

Это выражение вернёт строку 'Срочно'. Аналогично {{ $json.amount }} вернёт число 4200.

Expression вводится прямо в поле значения любого параметра узла. По умолчанию поле работает в режиме статического текста. Чтобы переключить его в режим expression, нужно нажать иконку молнии (⚡) справа от поля — после этого n8n начнёт вычислять содержимое как выражение, а не воспринимать его дословно.

Важно понимать разницу между статическим текстом и expression:

  • Статический текст: поле содержит Срочно — в Output будет 'Срочно' для всех items без исключения.
  • Expression: поле содержит {{ $json.priority }} — в Output будет то значение поля priority, которое пришло в конкретном item.

Если у вас на входе три items с разными значениями priority, expression вернёт три разных значения. Статический текст вернёт одно и то же три раза.

Кроме $json, в expressions есть и другие объекты. Один из них — $('NodeName').item.json.field — позволяет обратиться не к текущему item, а к данным конкретного узла по его имени. Это удобно, когда нужно «дотянуться» до данных, которые были в узле выше по цепочке, но не дошли до текущего напрямую. Однако в большинстве повседневных случаев достаточно $json.

Expression — это JavaScript, поэтому он чувствителен к регистру и точному написанию ключей. $json.Priority и $json.priority — это два разных обращения. Точное написание ключей критично — в следующих разделах разберём, что происходит, если допустить опечатку или забыть фигурные скобки.

Data mapping и вычисление новых значений в expressions

Читать поля через $json — это уже умеем. Следующий шаг: не просто передать существующее поле дальше, а либо явно связать поле выхода с полем входа, либо вычислить на его основе что-то новое.

Что такое mapping и как он задаётся

Mapping — это явное указание: «значение вот этого поля нового узла берётся из вот этого поля предыдущего узла». В n8n есть два способа его задать.

Первый — drag-and-drop: в панели Input рядом с именем поля есть иконка, по которой можно кликнуть или перетащить поле прямо в нужный параметр. n8n сам подставит expression вида {{ $json.fieldName }}. Удобно, если имена полей длинные или нужно не ошибиться в написании.

Второй — ввод expression вручную: переключаете поле в режим expression (иконка ⚡) и пишете {{ $json.fieldName }} самостоятельно. Результат тот же, просто быстрее, если имя поля простое и вы его помните.

Оба способа дают одинаковый результат в Output: поле нового item получает значение из входного item.

Вычисление нового значения

Expression — это JavaScript, поэтому внутри {{ }} можно не только читать поле, но и что-то с ним делать. Три основных сценария:

  • Конкатенация строк: объединить два поля в одно.
  • Арифметика: умножить, сложить, посчитать итог.
  • Условное значение: вернуть одно из двух значений в зависимости от условия.

Вот как это выглядит на практике. Предположим, входной item такой:

{
  "json": {
    "firstName": "Анна",
    "lastName": "Смирнова",
    "priority": "Срочно",
    "price": 1400,
    "qty": 3
  }
}

Тогда в узле Edit Fields можно задать три новых поля:

fullName  →  {{ $json.firstName + ' ' + $json.lastName }}
total     →  {{ $json.price * $json.qty }}
level     →  {{ $json.priority === 'Срочно' ? 'high' : 'normal' }}

В Output получится:

{
  "json": {
    "fullName": "Анна Смирнова",
    "total": 4200,
    "level": "high"
  }
}

Ни одно из этих трёх полей не существовало во входном item — они вычислены на месте. fullName — это конкатенация двух строк через пробел. total — произведение двух чисел. level — тернарный оператор: если priority равен строке 'Срочно', вернуть 'high', иначе 'normal'.

Полный цикл на примере fullName

Чтобы собрать это в голове как единое действие: берёте узел Edit Fields, добавляете поле с именем fullName, переключаете его значение в режим expression, вводите {{ $json.firstName + ' ' + $json.lastName }}. После запуска в Output появится новое поле — n8n вычислил его для каждого item из массива отдельно.

Если во входном массиве было три item с разными именами — в Output три item с тремя разными fullName. Никакого дополнительного цикла писать не нужно: n8n прогоняет expression по каждому item автоматически.

Маппинг через drag-and-drop и ручное вычисление через expression — это не разные механизмы, а два интерфейса к одному и тому же. В обоих случаях в поле оказывается {{ $json.поле }}, просто в первом случае n8n написал это за вас.

Типичные ошибки: опечатка в имени поля и забытые фигурные скобки

Две ошибки в expressions встречаются чаще всего — и обе коварны тем, что не вызывают явного сбоя. Workflow выполняется, узел отрабатывает, Output появляется. Только данные в нём не те.

Ошибка 1: опечатка в имени ключа → пустое поле в Output

Предположим, входной item содержит поле priority, а в expression написано:

{{ $json.prioryty }}

Типичная опечатка — переставлена буква. n8n не выдаст ошибку выполнения, потому что с точки зрения JavaScript обращение к несуществующему ключу — это не исключение, а просто undefined.

Результат: поле в Output есть, но его значение пустое.

Симптом в Output: колонка присутствует, значение — пусто или отображается как -.

Диагностика: открываете панель Input предыдущего узла, переключаетесь в режим JSON и смотрите точное написание ключа — не «на глаз», а посимвольно. После этого исправляете expression.

// Было (ошибка)
{{ $json.prioryty }}

// Стало (правильно)
{{ $json.priority }}

Практический совет: если скопировать имя ключа прямо из JSON-режима панели Input (или использовать drag-and-drop), риск опечатки и ошибки регистра исчезает — n8n подставит точное написание за вас. Набор вручную оправдан только для простых и хорошо знакомых имён.

Ошибка 2: забытые фигурные скобки → строковый литерал вместо значения

Вторая ошибка выглядит так: вы вводите в поле значения:

$json.priority

...без {{ }}. Если поле при этом остаётся в режиме статического текста (иконка молнии не нажата), n8n не вычисляет ничего — он просто записывает это как строку.

Результат в Output: поле получает значение $json.priority — буквально эти символы, а не то, что в них подразумевалось.

Симптом в Output: значение поля — это дословно написанный текст expression, например $json.priority или {{ $json.priority }} (если скобки были, но режим не переключён).

Диагностика и исправление: проверяете, активен ли режим expression — рядом с полем должна гореть иконка ⚡. Если нет — нажимаете её. Либо убеждаетесь, что значение обёрнуто в {{ }}:

// Было (ошибка — статический текст)
$json.priority

// Стало (правильно — expression)
{{ $json.priority }}

Как читать Output, чтобы поймать обе ошибки

Оба сбоя диагностируются одним действием: смотрите в Output и задаёте себе два вопроса.

  • Значение поля пустое? → скорее всего, опечатка в имени ключа. Идёте в JSON-режим Input и сверяете.
  • Значение поля — это дословный текст expression? → поле работает в режиме статического текста. Переключаете в expression.

Оба случая лечатся за одно действие, как только поставлен правильный диагноз. Именно поэтому привычка проверять Output в JSON-режиме после каждого изменения экономит время: визуального взгляда на таблицу часто достаточно, чтобы сразу увидеть, что что-то пошло не так.

Попробуйте решить

В узле Edit Fields ты хочешь создать поле label, которое будет содержать значение поля category из предыдущего узла. Какую запись нужно поставить в поле Value?

Продолжить с проверкой и прогрессом

Откройте интерактивный раннер с заданиями урока.

Перейти к интерактивному уроку