n8n-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

n8n 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

节点类型

TypePurposeExamples
TriggerStart workflowWebhook, Schedule, App trigger
ActionPerform operationsHTTP Request, Database, Email
TransformModify dataSet, Code, IF, Switch
FlowControl executionMerge, 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
    responseNode
    for custom responses
  • Enable
    rawBody
    for signature verification
  • 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:
  • 0 * * * *
    - Every hour
  • 0 9 * * 1-5
    - Weekdays at 9 AM
  • 0 0 * * 0
    - Weekly on Sunday midnight
  • */15 * * * *
    - Every 15 minutes
json
{
  "name": "Schedule Trigger",
  "type": "n8n-nodes-base.scheduleTrigger",
  "parameters": {
    "rule": {
      "interval": [
        {
          "field": "cronExpression",
          "expression": "0 9 * * 1-5"
        }
      ]
    }
  }
}
常见调度规则:
  • 0 * * * *
    - 每小时执行一次
  • 0 9 * * 1-5
    - 工作日上午9点执行
  • 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
undefined
python
undefined

Enable 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
undefined
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
undefined

Control 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
    waitForSubWorkflow
    based on needs
  • 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

凭据类型

TypeUse Case
httpBasicAuth
Basic authentication
httpHeaderAuth
API key in header
oAuth2Api
OAuth 2.0 flows
httpQueryAuth
API key in query string
类型使用场景
httpBasicAuth
基础身份验证
httpHeaderAuth
头部携带API密钥
oAuth2Api
OAuth 2.0流程
httpQueryAuth
查询字符串中携带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
undefined
bash
undefined

n8n 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
undefined
EXECUTIONS_MODE=queue QUEUE_BULL_REDIS_HOST=redis
undefined

Queue Mode (Scaling)

队列模式(扩展)

yaml
undefined
yaml
undefined

docker-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
undefined
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
undefined

Common 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

表达式速查表

ExpressionDescription
{{ $json.field }}
Access field from current item
{{ $json["field-name"] }}
Access field with special chars
{{ $('NodeName').item.json.field }}
Access data from specific node
{{ $input.first().json }}
First input item
{{ $input.all() }}
All input items
{{ $env.VAR_NAME }}
Environment variable
{{ $now }}
Current datetime
{{ $today }}
Current date
{{ $runIndex }}
Current execution run index
{{ $itemIndex }}
Current item index
{{ $workflow.id }}
Workflow ID
{{ $execution.id }}
Execution ID
表达式说明
{{ $json.field }}
访问当前项目中的字段
{{ $json["field-name"] }}
访问包含特殊字符的字段
{{ $('NodeName').item.json.field }}
访问指定节点的数据
{{ $input.first().json }}
第一个输入项目
{{ $input.all() }}
所有输入项目
{{ $env.VAR_NAME }}
环境变量
{{ $now }}
当前日期时间
{{ $today }}
当前日期
{{ $runIndex }}
当前执行运行索引
{{ $itemIndex }}
当前项目索引
{{ $workflow.id }}
工作流ID
{{ $execution.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 string
javascript
// 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

最佳实践

  1. Naming: Use descriptive node names (verb + noun)
  2. Error Handling: Always add error workflows
  3. Credentials: Never hardcode secrets
  4. Batching: Use
    splitInBatches
    for large datasets
  5. Timeouts: Set appropriate timeouts on HTTP nodes
  6. Logging: Use
    console.log
    in Code nodes for debugging
  7. Testing: Use manual execution before activating
  8. Version Control: Export workflows as JSON to git
  9. Documentation: Add sticky notes for complex logic
  10. Modular Design: Use sub-workflows for reusability
  1. 命名规范:使用描述性节点名称(动词+名词)
  2. 错误处理:始终添加错误处理工作流
  3. 凭据管理:切勿硬编码密钥
  4. 批量处理:对大型数据集使用
    splitInBatches
  5. 超时设置:为HTTP节点设置合理的超时时间
  6. 日志调试:在Code节点中使用
    console.log
    进行调试
  7. 测试验证:激活前先手动执行测试
  8. 版本控制:将工作流导出为JSON并提交到Git
  9. 文档说明:为复杂逻辑添加便签注释
  10. 模块化设计:使用子工作流实现逻辑复用

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()
  }
}];

Resources

资源