Глава 3. Данные и выражения
В n8n данные — это не просто набор переменных. У них есть чёткая структура, которую важно понять, чтобы уверенно работать с любыми нодами. В этой главе разберём, как данные текут через воркфлоу, как обращаться к ним через выражения и как трансформировать их с помощью нод Set и Code.
Как данные текут между нодами
Каждая нода получает на вход массив элементов (items) и возвращает новый массив элементов. Это центральная идея n8n.
Нода A → [ item1, item2, item3 ] → Нода BНода B обработает каждый элемент по очереди (если не указано иное). Это значит, что одно HTTP-соединение может вернуть несколько строк — и следующая нода обработает каждую из них.
Структура элемента (Item)
Каждый элемент массива выглядит так:
{
"json": {
"id": 42,
"name": "Иван Петров",
"email": "ivan@example.com",
"score": 95
},
"binary": {}
}json— основные данные в виде произвольного объекта.binary— бинарные данные: файлы, изображения. В большинстве воркфлоу пустой.
Откуда берётся структура?
Каждая нода формирует json самостоятельно. HTTP Request помещает ответ сервера в json. Google Sheets — каждую строку. Нода Webhook — тело входящего запроса.
Выражения (Expressions)
Выражения позволяют динамически обращаться к данным прямо в полях нод. Они заключаются в двойные фигурные скобки:
{{ выражение }}Базовый синтаксис
Обращение к полю текущего элемента:
{{ $json.name }}
{{ $json.current_condition[0].temp_C }}
{{ $json.user.address.city }}Результат выражения подставляется как строка в поле ноды.
Встроенные переменные
| Переменная | Что возвращает |
|---|---|
$json | Объект json текущего элемента |
$input.first() | Первый элемент из входных данных |
$input.all() | Все входные элементы массивом |
$input.item | Текущий обрабатываемый элемент |
$node["Название ноды"].json | Вывод конкретной ноды по имени |
$env.MY_VAR | Переменная окружения |
$execution.id | ID текущего выполнения воркфлоу |
$now | Текущее время в формате Luxon DateTime |
$today | Сегодняшняя дата |
Примеры выражений
Преобразовать имя в верхний регистр:
{{ $json.name.toUpperCase() }}Отформатировать дату:
{{ $now.toFormat(dd.MM.yyyy HH:mm) }}Обратиться к выводу конкретной ноды:
{{ $node["HTTP Request"].json.temperature }}Вычислить значение:
{{ $json.price * $json.quantity }}Тернарный оператор:
{{ $json.score >= 80 ? "Отлично" : "Требует улучшения" }}Нода Set — изменить или добавить поля
Нода Set позволяет добавлять новые поля, изменять существующие или оставлять только нужные — без написания кода.
Пример: у нас есть данные пользователя, и мы хотим добавить поле fullName и убрать лишние поля:
Настройка ноды Set:
Режим: Manual Mapping
Поля:
fullName = {{ $json.firstName + " " + $json.lastName }}
email = {{ $json.email }}Включите Keep Only Set — тогда в выходных данных останутся только те поля, которые вы указали явно.
Когда использовать Set, а когда Code?
Используйте Set для простых трансформаций: переименовать поле, объединить строки, отфильтровать данные. Переходите на Code, когда нужны циклы, условия, внешние вычисления или работа со всем массивом сразу.
Нода Code — полноценный JavaScript
Нода Code даёт полную свободу: здесь можно писать любой JavaScript.
Режим «Run Once for Each Item»
Код выполняется для каждого элемента отдельно. Текущий элемент доступен через $input.item:
const item = $input.item.json;
// Рассчитываем итоговую цену со скидкой
const discount = item.vipClient ? 0.15 : 0;
const finalPrice = item.price * (1 - discount);
return {
json: {
...item,
discount: `${discount * 100}%`,
finalPrice: Math.round(finalPrice),
}
};Режим «Run Once for All Items»
Код выполняется один раз, получает весь массив через $input.all(). Удобно для агрегации:
const items = $input.all();
// Считаем статистику по всем элементам
const scores = items.map(i => i.json.score);
const avg = scores.reduce((a, b) => a + b, 0) / scores.length;
const max = Math.max(...scores);
const min = Math.min(...scores);
return [
{
json: {
count: items.length,
average: Math.round(avg),
max,
min,
}
}
];Полный пример: форматирование погоды
Вернёмся к примеру из предыдущей главы — посмотрим на него подробнее:
const condition = $input.first().json.current_condition[0];
const forecast = $input.first().json.weather[0];
// Деструктурируем нужные поля
const { temp_C, FeelsLikeC, humidity, windspeedKmph } = condition;
const desc = condition.weatherDesc[0].value;
const maxTemp = forecast.maxtempC;
const minTemp = forecast.mintempC;
// Формируем строку сообщения
const lines = [
`🌤 Погода в Москве:`,
``,
`🌡 ${temp_C}°C (ощущается как ${FeelsLikeC}°C)`,
`🌥 ${desc}`,
`💧 Влажность: ${humidity}%`,
`💨 Ветер: ${windspeedKmph} км/ч`,
``,
`📅 Сегодня: от ${minTemp}°C до ${maxTemp}°C`,
];
return [{ json: { message: lines.join("\n") } }];Переменные окружения
Для хранения секретов (API-ключей, токенов) используйте переменные окружения — их можно задать в файле .env при запуске n8n:
# .env
MY_API_KEY=sk-abc123
TELEGRAM_CHAT_ID=123456789Или при запуске через Docker:
docker run -it --rm \
-p 5678:5678 \
-e MY_API_KEY=sk-abc123 \
n8nio/n8nОбратиться к переменной в выражении:
{{ $env.MY_API_KEY }}Безопасность
Не храните секреты прямо в полях нод — они сохраняются в базе данных воркфлоу и могут быть видны при экспорте. Используйте Credentials или переменные окружения.
Вы освоили три ключевые темы: структуру данных, выражения и трансформацию. Этих знаний достаточно, чтобы строить сложные воркфлоу в n8n.