N8N中文教程
集成节点/Creating_nodes/Plan_your_node

选择节点构建方式#

n8n 提供两种节点构建风格:声明式(declarative)和编程式(programmatic)。

大多数节点建议使用声明式风格,这种风格:

  • 采用基于 JSON 的语法,编写更简单,引入错误的风险更低
  • 更具未来兼容性
  • 支持与 REST API 集成

编程式风格更为冗长。以下情况必须使用编程式风格:

  • 触发器节点(Trigger nodes)
  • 非基于 REST 的节点(包括需要调用 GraphQL API 的节点和使用外部依赖的节点)
  • 需要转换输入数据的节点
  • 完整版本控制。有关版本控制类型的更多信息,请参阅节点版本控制

数据处理差异#

声明式与编程式风格的主要区别在于处理输入数据和构建 API 请求的方式。编程式风格需要实现 execute() 方法,该方法负责读取输入数据和参数,然后构建请求。声明式风格则通过 operations 对象中的 routing 键来处理这些操作。有关节点参数和 execute() 方法的更多信息,请参阅节点基础文件

语法差异#

通过对比以下两个代码片段可以理解声明式与编程式风格的区别。本例创建了 SendGrid 集成的一个简化版本,称为 "FriendGrid"。以下代码片段并不完整,主要突出节点构建风格的差异。

编程式风格:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

| ``` import{ IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, IRequestOptions, }from'n8n-workflow';


```typescript
import { INodeType, INodeTypeDescription } from 'n8n-workflow';

// 创建 FriendGrid 类
export class FriendGrid implements INodeType {
	description: INodeTypeDescription = {
		displayName: 'FriendGrid',
		name: 'friendGrid',
		...
		// 设置基本请求配置
		requestDefaults: {
			baseURL: 'https://api.sendgrid.com/v3/marketing'
		},
		properties: [
			{
				displayName: 'Resource',
				...
			},
			{
				displayName: 'Operation',
				name: 'operation',
				type: 'options',
				displayOptions: {
					show: {
						resource: [
							'contact',
						],
					},
				},
				options: [
					{
						name: 'Create',
						value: 'create',
						description: '创建联系人',
						// 添加路由对象
						routing: {
							request: {
								method: 'POST',
								url: '=/contacts',
								send: {
									type: 'body',
									properties: {
										email: {{$parameter["email"]}}
									}
								}
							}
						},
						// 处理联系人创建的响应
						output: {
							postReceive: [
								{
									type: 'set',
									properties: {
										value: '={{ { "success": $response } }}'
									}
								}
							]
						}
					},
				],
				default: 'create',
				description: '要执行的操作',
			},
			{
				displayName: 'Email',
				...
			},
			{
				displayName: 'Additional Fields',
				// 设置可选字段
			},
		],
	}
	// 无需 execute 方法
}

以声明式风格:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

| ```typescript import { INodeType, INodeTypeDescription } from 'n8n-workflow';

// 创建 FriendGrid 类 export class FriendGrid implements INodeType { description: INodeTypeDescription = { displayName: 'FriendGrid', name: 'friendGrid', ... properties: [ { displayName: 'Resource', ... }, { displayName: 'Operation', name: 'operation', type: 'options', displayOptions: { show: { resource: [ 'contact', ], }, }, options: [ { name: 'Create', value: 'create', description: '创建联系人', }, ], default: 'create', description: '要执行的操作', }, { displayName: 'Email', name: 'email', ... }, { displayName: 'Additional Fields', // 设置可选字段 }, ], };

async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
	let responseData;
	const resource = this.getNodeParameter('resource', 0) as string;
	const operation = this.getNodeParameter('operation', 0) as string;
	// 获取用户为此节点提供的凭据
	const credentials = await this.getCredentials('friendGridApi') as IDataObject;

	if (resource === 'contact') {
		if (operation === 'create') {
			// 获取邮箱输入
			const email = this.getNodeParameter('email', 0) as string;
			// 获取附加字段输入
			const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject;
			const data: IDataObject = {
				email,
			};

			Object.assign(data, additionalFields);

			// 按照 https://sendgrid.com/docs/api-reference/ 中的定义发起 HTTP 请求
			const options: IRequestOptions = {
				headers: {
					'Accept': 'application/json',
					'Authorization': `Bearer ${credentials.apiKey}`,
				},
				method: 'PUT',
				body: {
					contacts: [
						data,
					],
				},
				url: `https://api.sendgrid.com/v3/marketing/contacts`,
				json: true,
			};
			responseData = await this.helpers.httpRequest(options);
		}
	}
	// 将数据映射到 n8n 数据格式
	return [this.helpers.returnJsonArray(responseData)];
}

}

---|---