n8n-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesen8n Workflow Patterns
n8n工作流模式
Build robust workflow automations with n8n - the open-source workflow automation tool.
借助n8n——开源工作流自动化工具——构建可靠的工作流自动化。
Overview
概述
n8n is a self-hostable workflow automation platform that connects apps and services. Key features:
- Visual workflow builder with 400+ integrations
- Self-hosted or cloud deployment
- Code nodes for custom logic (JavaScript/Python)
- Webhook triggers for real-time automation
- Sub-workflows for modular design
n8n是一款可自托管的工作流自动化平台,用于连接各类应用与服务。核心特性:
- 可视化工作流构建器,支持400+集成
- 可自托管或云端部署
- 支持自定义逻辑的代码节点(JavaScript/Python)
- 用于实时自动化的Webhook触发器
- 用于模块化设计的子工作流
Core Concepts
核心概念
Workflow Structure
工作流结构
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Trigger │───▶│ Node │───▶│ Output │
│ (Start) │ │ (Process) │ │ (Action) │
└─────────────┘ └─────────────┘ └─────────────┘┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Trigger │───▶│ Node │───▶│ Output │
│ (Start) │ │ (Process) │ │ (Action) │
└─────────────┘ └─────────────┘ └─────────────┘Node Types
节点类型
| Type | Purpose | Examples |
|---|---|---|
| Trigger | Start workflow | Webhook, Schedule, App trigger |
| Action | Perform operations | HTTP Request, Database, Email |
| Transform | Modify data | Set, Code, IF, Switch |
| Flow | Control execution | Merge, Split, Wait, Loop |
| 类型 | 用途 | 示例 |
|---|---|---|
| Trigger(触发器) | 启动工作流 | Webhook、Schedule(调度)、App trigger(应用触发器) |
| Action(动作) | 执行操作 | HTTP Request(HTTP请求)、Database(数据库)、Email(邮件) |
| Transform(转换) | 处理数据 | Set(设置)、Code(代码)、IF(条件判断)、Switch(分支切换) |
| Flow(流控制) | 控制执行流程 | Merge(合并)、Split(拆分)、Wait(等待)、Loop(循环) |
Trigger Patterns
触发器模式
Webhook Trigger
Webhook触发器
json
{
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": {
"httpMethod": "POST",
"path": "my-webhook",
"responseMode": "responseNode",
"options": {
"rawBody": true
}
}
}
]
}Best Practices:
- Use for custom responses
responseNode - Enable for signature verification
rawBody - Add authentication (Header Auth, Basic Auth)
json
{
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": {
"httpMethod": "POST",
"path": "my-webhook",
"responseMode": "responseNode",
"options": {
"rawBody": true
}
}
}
]
}最佳实践:
- 使用实现自定义响应
responseNode - 启用用于签名验证
rawBody - 添加身份验证(Header Auth、Basic Auth)
Schedule Trigger
调度触发器
json
{
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * 1-5"
}
]
}
}
}Common Schedules:
- - Every hour
0 * * * * - - Weekdays at 9 AM
0 9 * * 1-5 - - Weekly on Sunday midnight
0 0 * * 0 - - Every 15 minutes
*/15 * * * *
json
{
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * 1-5"
}
]
}
}
}常见调度规则:
- - 每小时执行一次
0 * * * * - - 工作日上午9点执行
0 9 * * 1-5 - - 每周日午夜执行
0 0 * * 0 - - 每15分钟执行一次
*/15 * * * *
App Trigger (Polling)
应用触发器(轮询)
json
{
"name": "GitHub Trigger",
"type": "n8n-nodes-base.githubTrigger",
"parameters": {
"owner": "{{$env.GITHUB_OWNER}}",
"repository": "{{$env.GITHUB_REPO}}",
"events": ["issues", "pull_request"]
}
}json
{
"name": "GitHub Trigger",
"type": "n8n-nodes-base.githubTrigger",
"parameters": {
"owner": "{{$env.GITHUB_OWNER}}",
"repository": "{{$env.GITHUB_REPO}}",
"events": ["issues", "pull_request"]
}
}Data Transformation Patterns
数据转换模式
Set Node (Transform Data)
Set节点(数据转换)
json
{
"name": "Transform Data",
"type": "n8n-nodes-base.set",
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"name": "fullName",
"value": "={{ $json.firstName }} {{ $json.lastName }}",
"type": "string"
},
{
"name": "timestamp",
"value": "={{ DateTime.now().toISO() }}",
"type": "string"
}
]
}
}
}json
{
"name": "Transform Data",
"type": "n8n-nodes-base.set",
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"name": "fullName",
"value": "={{ $json.firstName }} {{ $json.lastName }}",
"type": "string"
},
{
"name": "timestamp",
"value": "={{ DateTime.now().toISO() }}",
"type": "string"
}
]
}
}
}Code Node (JavaScript)
Code节点(JavaScript)
javascript
// Process items with custom logic
const results = [];
for (const item of $input.all()) {
const data = item.json;
// Transform data
results.push({
json: {
id: data.id,
processed: true,
score: calculateScore(data),
timestamp: new Date().toISOString()
}
});
}
function calculateScore(data) {
return data.value * 0.8 + data.bonus * 0.2;
}
return results;javascript
// Process items with custom logic
const results = [];
for (const item of $input.all()) {
const data = item.json;
// Transform data
results.push({
json: {
id: data.id,
processed: true,
score: calculateScore(data),
timestamp: new Date().toISOString()
}
});
}
function calculateScore(data) {
return data.value * 0.8 + data.bonus * 0.2;
}
return results;Code Node (Python)
Code节点(Python)
python
undefinedpython
undefinedEnable Python in n8n settings
Enable Python in n8n settings
import json
from datetime import datetime
results = []
for item in _input.all():
data = item.json
# Transform data
results.append({
"json": {
"id": data.get("id"),
"processed": True,
"timestamp": datetime.now().isoformat()
}
})return results
undefinedimport json
from datetime import datetime
results = []
for item in _input.all():
data = item.json
# Transform data
results.append({
"json": {
"id": data.get("id"),
"processed": True,
"timestamp": datetime.now().isoformat()
}
})return results
undefinedControl Flow Patterns
流控制模式
IF Node (Conditional)
IF节点(条件判断)
json
{
"name": "Check Status",
"type": "n8n-nodes-base.if",
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"leftValue": "={{ $json.status }}",
"rightValue": "active",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
}
}
}json
{
"name": "Check Status",
"type": "n8n-nodes-base.if",
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"leftValue": "={{ $json.status }}",
"rightValue": "active",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
}
}
}Switch Node (Multi-branch)
Switch节点(多分支)
json
{
"name": "Route by Type",
"type": "n8n-nodes-base.switch",
"parameters": {
"mode": "rules",
"rules": {
"values": [
{
"outputKey": "order",
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.type }}",
"rightValue": "order",
"operator": { "type": "string", "operation": "equals" }
}
]
}
},
{
"outputKey": "refund",
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.type }}",
"rightValue": "refund",
"operator": { "type": "string", "operation": "equals" }
}
]
}
}
]
},
"fallbackOutput": "extra"
}
}json
{
"name": "Route by Type",
"type": "n8n-nodes-base.switch",
"parameters": {
"mode": "rules",
"rules": {
"values": [
{
"outputKey": "order",
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.type }}",
"rightValue": "order",
"operator": { "type": "string", "operation": "equals" }
}
]
}
},
{
"outputKey": "refund",
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.type }}",
"rightValue": "refund",
"operator": { "type": "string", "operation": "equals" }
}
]
}
}
]
},
"fallbackOutput": "extra"
}
}Loop Over Items
循环处理项目
json
{
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"parameters": {
"batchSize": 10,
"options": {
"reset": false
}
}
}json
{
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"parameters": {
"batchSize": 10,
"options": {
"reset": false
}
}
}Merge Node (Combine Data)
Merge节点(数据合并)
json
{
"name": "Merge Results",
"type": "n8n-nodes-base.merge",
"parameters": {
"mode": "combine",
"mergeByFields": {
"values": [
{
"field1": "id",
"field2": "userId"
}
]
},
"options": {}
}
}json
{
"name": "Merge Results",
"type": "n8n-nodes-base.merge",
"parameters": {
"mode": "combine",
"mergeByFields": {
"values": [
{
"field1": "id",
"field2": "userId"
}
]
},
"options": {}
}
}Error Handling Patterns
错误处理模式
Try/Catch with Error Trigger
结合Error Trigger的Try/Catch
json
{
"nodes": [
{
"name": "Error Trigger",
"type": "n8n-nodes-base.errorTrigger",
"parameters": {}
},
{
"name": "Send Alert",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#alerts",
"text": "Workflow failed: {{ $json.workflow.name }}\nError: {{ $json.execution.error.message }}"
}
}
]
}json
{
"nodes": [
{
"name": "Error Trigger",
"type": "n8n-nodes-base.errorTrigger",
"parameters": {}
},
{
"name": "Send Alert",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#alerts",
"text": "Workflow failed: {{ $json.workflow.name }}\nError: {{ $json.execution.error.message }}"
}
}
]
}最佳实践:
- 使用实现自定义响应
responseNode - 启用用于签名验证
rawBody - 添加身份验证(Header Auth、Basic Auth)
Retry on Failure
失败时重试
json
{
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.example.com/data",
"options": {}
},
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1000
}json
{
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.example.com/data",
"options": {}
},
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1000
}Stop and Error Node
Stop and Error节点
json
{
"name": "Validation Failed",
"type": "n8n-nodes-base.stopAndError",
"parameters": {
"errorMessage": "Invalid input: {{ $json.error }}"
}
}json
{
"name": "Validation Failed",
"type": "n8n-nodes-base.stopAndError",
"parameters": {
"errorMessage": "Invalid input: {{ $json.error }}"
}
}Sub-Workflow Pattern
子工作流模式
Execute Workflow Node
Execute Workflow节点
json
{
"name": "Process Order",
"type": "n8n-nodes-base.executeWorkflow",
"parameters": {
"source": "database",
"workflowId": "order-processing-workflow-id",
"mode": "each",
"options": {
"waitForSubWorkflow": true
}
}
}Best Practices:
- Use sub-workflows for reusable logic
- Pass minimal data between workflows
- Set based on needs
waitForSubWorkflow - Use workflow tags for organization
json
{
"name": "Process Order",
"type": "n8n-nodes-base.executeWorkflow",
"parameters": {
"source": "database",
"workflowId": "order-processing-workflow-id",
"mode": "each",
"options": {
"waitForSubWorkflow": true
}
}
}最佳实践:
- 将可复用逻辑封装为子工作流
- 在工作流之间传递最少必要数据
- 根据需求设置
waitForSubWorkflow - 使用工作流标签进行组织
HTTP Request Patterns
HTTP请求模式
REST API Call
REST API调用
json
{
"name": "API Request",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://api.example.com/v1/resource",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "data",
"value": "={{ JSON.stringify($json) }}"
}
]
},
"options": {
"timeout": 30000,
"response": {
"response": {
"fullResponse": false,
"responseFormat": "json"
}
}
}
}
}json
{
"name": "API Request",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"method": "POST",
"url": "https://api.example.com/v1/resource",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "data",
"value": "={{ JSON.stringify($json) }}"
}
]
},
"options": {
"timeout": 30000,
"response": {
"response": {
"fullResponse": false,
"responseFormat": "json"
}
}
}
}
}Pagination Pattern
分页模式
javascript
// Code node for API pagination
const allResults = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await this.helpers.httpRequest({
method: 'GET',
url: `https://api.example.com/items?page=${page}&limit=100`,
headers: {
'Authorization': `Bearer ${$env.API_TOKEN}`
}
});
allResults.push(...response.data);
hasMore = response.hasNextPage;
page++;
// Rate limiting
await new Promise(r => setTimeout(r, 100));
}
return allResults.map(item => ({ json: item }));javascript
// Code node for API pagination
const allResults = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await this.helpers.httpRequest({
method: 'GET',
url: `https://api.example.com/items?page=${page}&limit=100`,
headers: {
'Authorization': `Bearer ${$env.API_TOKEN}`
}
});
allResults.push(...response.data);
hasMore = response.hasNextPage;
page++;
// Rate limiting
await new Promise(r => setTimeout(r, 100));
}
return allResults.map(item => ({ json: item }));Credential Management
凭据管理
Environment Variables
环境变量
javascript
// Access in expressions
{{ $env.API_KEY }}
{{ $env.DATABASE_URL }}
// Access in Code node
const apiKey = $env.API_KEY;javascript
// Access in expressions
{{ $env.API_KEY }}
{{ $env.DATABASE_URL }}
// Access in Code node
const apiKey = $env.API_KEY;Credential Types
凭据类型
| Type | Use Case |
|---|---|
| Basic authentication |
| API key in header |
| OAuth 2.0 flows |
| API key in query string |
| 类型 | 使用场景 |
|---|---|
| 基础身份验证 |
| 头部携带API密钥 |
| OAuth 2.0流程 |
| 查询字符串中携带API密钥 |
Self-Hosting Patterns
自托管模式
Docker Compose
Docker Compose部署
yaml
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
- N8N_HOST=${N8N_HOST}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://${N8N_HOST}/
- GENERIC_TIMEZONE=UTC
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- postgres
postgres:
image: postgres:15
restart: unless-stopped
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
volumes:
n8n_data:
postgres_data:yaml
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
- N8N_HOST=${N8N_HOST}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://${N8N_HOST}/
- GENERIC_TIMEZONE=UTC
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- postgres
postgres:
image: postgres:15
restart: unless-stopped
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
volumes:
n8n_data:
postgres_data:Environment Variables (.env)
环境变量配置(.env)
bash
undefinedbash
undefinedn8n Configuration
n8n Configuration
N8N_HOST=n8n.example.com
N8N_USER=admin
N8N_PASSWORD=secure-password-here
N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
N8N_HOST=n8n.example.com
N8N_USER=admin
N8N_PASSWORD=secure-password-here
N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
Database
Database
POSTGRES_USER=n8n
POSTGRES_PASSWORD=secure-db-password
POSTGRES_USER=n8n
POSTGRES_PASSWORD=secure-db-password
Optional: Queue mode for scaling
Optional: Queue mode for scaling
EXECUTIONS_MODE=queue
QUEUE_BULL_REDIS_HOST=redis
undefinedEXECUTIONS_MODE=queue
QUEUE_BULL_REDIS_HOST=redis
undefinedQueue Mode (Scaling)
队列模式(扩展)
yaml
undefinedyaml
undefineddocker-compose.queue.yml
docker-compose.queue.yml
services:
n8n:
environment:
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_HEALTH_CHECK_ACTIVE=true
n8n-worker:
image: n8nio/n8n:latest
command: worker
environment:
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
deploy:
replicas: 3
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
undefinedservices:
n8n:
environment:
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_HEALTH_CHECK_ACTIVE=true
n8n-worker:
image: n8nio/n8n:latest
command: worker
environment:
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
deploy:
replicas: 3
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
undefinedCommon Workflow Templates
常见工作流模板
Webhook to Database
Webhook转数据库
json
{
"name": "Webhook to Database",
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": {
"httpMethod": "POST",
"path": "ingest",
"responseMode": "responseNode"
}
},
{
"name": "Validate",
"type": "n8n-nodes-base.if",
"parameters": {
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.id }}",
"rightValue": "",
"operator": { "type": "string", "operation": "notEmpty" }
}
]
}
}
},
{
"name": "Insert",
"type": "n8n-nodes-base.postgres",
"parameters": {
"operation": "insert",
"table": "events",
"columns": "id,type,data,created_at"
}
},
{
"name": "Success Response",
"type": "n8n-nodes-base.respondToWebhook",
"parameters": {
"respondWith": "json",
"responseBody": "={{ { \"success\": true, \"id\": $json.id } }}"
}
}
]
}json
{
"name": "Webhook to Database",
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": {
"httpMethod": "POST",
"path": "ingest",
"responseMode": "responseNode"
}
},
{
"name": "Validate",
"type": "n8n-nodes-base.if",
"parameters": {
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.id }}",
"rightValue": "",
"operator": { "type": "string", "operation": "notEmpty" }
}
]
}
}
},
{
"name": "Insert",
"type": "n8n-nodes-base.postgres",
"parameters": {
"operation": "insert",
"table": "events",
"columns": "id,type,data,created_at"
}
},
{
"name": "Success Response",
"type": "n8n-nodes-base.respondToWebhook",
"parameters": {
"respondWith": "json",
"responseBody": "={{ { \"success\": true, \"id\": $json.id } }}"
}
}
]
}Scheduled Sync
定时同步
json
{
"name": "Daily Data Sync",
"nodes": [
{
"name": "Schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [{ "field": "cronExpression", "expression": "0 2 * * *" }]
}
}
},
{
"name": "Fetch Source",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.source.com/data",
"authentication": "predefinedCredentialType"
}
},
{
"name": "Transform",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "return $input.all().map(item => ({ json: { ...item.json, synced_at: new Date().toISOString() } }));"
}
},
{
"name": "Upsert Destination",
"type": "n8n-nodes-base.postgres",
"parameters": {
"operation": "upsert",
"table": "synced_data"
}
}
]
}json
{
"name": "Daily Data Sync",
"nodes": [
{
"name": "Schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [{ "field": "cronExpression", "expression": "0 2 * * *" }]
}
}
},
{
"name": "Fetch Source",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.source.com/data",
"authentication": "predefinedCredentialType"
}
},
{
"name": "Transform",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "return $input.all().map(item => ({ json: { ...item.json, synced_at: new Date().toISOString() } }));"
}
},
{
"name": "Upsert Destination",
"type": "n8n-nodes-base.postgres",
"parameters": {
"operation": "upsert",
"table": "synced_data"
}
}
]
}Event-Driven Notification
事件驱动通知
json
{
"name": "Alert Pipeline",
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": { "path": "alert" }
},
{
"name": "Route by Severity",
"type": "n8n-nodes-base.switch",
"parameters": {
"rules": {
"values": [
{ "outputKey": "critical", "conditions": { "conditions": [{ "leftValue": "={{ $json.severity }}", "rightValue": "critical" }] } },
{ "outputKey": "warning", "conditions": { "conditions": [{ "leftValue": "={{ $json.severity }}", "rightValue": "warning" }] } }
]
}
}
},
{
"name": "Page On-Call",
"type": "n8n-nodes-base.pagerDuty"
},
{
"name": "Slack Alert",
"type": "n8n-nodes-base.slack"
}
]
}json
{
"name": "Alert Pipeline",
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": { "path": "alert" }
},
{
"name": "Route by Severity",
"type": "n8n-nodes-base.switch",
"parameters": {
"rules": {
"values": [
{ "outputKey": "critical", "conditions": { "conditions": [{ "leftValue": "={{ $json.severity }}", "rightValue": "critical" }] } },
{ "outputKey": "warning", "conditions": { "conditions": [{ "leftValue": "={{ $json.severity }}", "rightValue": "warning" }] } }
]
}
}
},
{
"name": "Page On-Call",
"type": "n8n-nodes-base.pagerDuty"
},
{
"name": "Slack Alert",
"type": "n8n-nodes-base.slack"
}
]
}Expression Cheat Sheet
表达式速查表
| Expression | Description |
|---|---|
| Access field from current item |
| Access field with special chars |
| Access data from specific node |
| First input item |
| All input items |
| Environment variable |
| Current datetime |
| Current date |
| Current execution run index |
| Current item index |
| Workflow ID |
| Execution ID |
| 表达式 | 说明 |
|---|---|
| 访问当前项目中的字段 |
| 访问包含特殊字符的字段 |
| 访问指定节点的数据 |
| 第一个输入项目 |
| 所有输入项目 |
| 环境变量 |
| 当前日期时间 |
| 当前日期 |
| 当前执行运行索引 |
| 当前项目索引 |
| 工作流ID |
| 执行ID |
Luxon DateTime Examples
Luxon DateTime示例
javascript
// n8n uses Luxon for dates
{{ $now.toISO() }} // ISO format
{{ $now.toFormat('yyyy-MM-dd') }} // Custom format
{{ $now.plus({ days: 7 }).toISO() }} // Add 7 days
{{ $now.startOf('month').toISO() }} // Start of month
{{ DateTime.fromISO($json.date) }} // Parse ISO stringjavascript
// n8n uses Luxon for dates
{{ $now.toISO() }} // ISO格式
{{ $now.toFormat('yyyy-MM-dd') }} // 自定义格式
{{ $now.plus({ days: 7 }).toISO() }} // 添加7天
{{ $now.startOf('month').toISO() }} // 月初时间
{{ DateTime.fromISO($json.date) }} // 解析ISO字符串Best Practices
最佳实践
- Naming: Use descriptive node names (verb + noun)
- Error Handling: Always add error workflows
- Credentials: Never hardcode secrets
- Batching: Use for large datasets
splitInBatches - Timeouts: Set appropriate timeouts on HTTP nodes
- Logging: Use in Code nodes for debugging
console.log - Testing: Use manual execution before activating
- Version Control: Export workflows as JSON to git
- Documentation: Add sticky notes for complex logic
- Modular Design: Use sub-workflows for reusability
- 命名规范:使用描述性节点名称(动词+名词)
- 错误处理:始终添加错误处理工作流
- 凭据管理:切勿硬编码密钥
- 批量处理:对大型数据集使用
splitInBatches - 超时设置:为HTTP节点设置合理的超时时间
- 日志调试:在Code节点中使用进行调试
console.log - 测试验证:激活前先手动执行测试
- 版本控制:将工作流导出为JSON并提交到Git
- 文档说明:为复杂逻辑添加便签注释
- 模块化设计:使用子工作流实现逻辑复用
Debugging Tips
调试技巧
javascript
// In Code node - log to n8n console
console.log('Debug:', JSON.stringify($json, null, 2));
// Return debug info
return [{
json: {
debug: true,
input: $json,
env: $env.NODE_ENV,
timestamp: new Date().toISOString()
}
}];javascript
// In Code node - log to n8n console
console.log('Debug:', JSON.stringify($json, null, 2));
// Return debug info
return [{
json: {
debug: true,
input: $json,
env: $env.NODE_ENV,
timestamp: new Date().toISOString()
}
}];