跳到主要内容

选择节点构建方式#

n8n提供两种节点构建风格:声明式与编程式。

多数节点建议采用声明式风格,该风格具有以下特点:

  • 采用基于JSON的语法,编写更简便且能降低代码缺陷风险
  • 具备更好的未来兼容性
  • 支持REST API集成

编程式风格更为冗长,以下场景必须使用该风格:

  • 触发器节点
  • 非REST架构节点(包括需调用GraphQL接口的节点及使用外部依赖的节点)
  • 需对输入数据进行转换处理的节点
  • 完整版本控制需求(详见节点版本控制了解版本控制类型)

数据处理差异#

两种风格的核心差异在于数据处理与API请求构建方式:编程式需通过execute()方法读取输入数据及参数后构建请求,而声明式通过operations对象中的routing键实现该功能。关于节点参数与execute()方法的详细信息,请参阅节点基础文件

语法差异#

通过以下代码片段对比可直观理解两种风格的差异。本例创建了SendGrid集成的简化版"FriendGrid",注意这些片段仅为突出构建风格差异的非完整示例:

编程式风格:

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

// Create the FriendGrid class
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: 'Create a contact',
},
],
default: 'create',
description: 'The operation to perform.',
},
{
displayName: 'Email',
name: 'email',
. . .
},
{
displayName: 'Additional Fields',
// Sets up optional 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;
//Get credentials the user provided for this node
const credentials = await this.getCredentials('friendGridApi') as IDataObject;

if (resource === 'contact') {
if (operation === 'create') {
// Get email input
const email = this.getNodeParameter('email', 0) as string;
// Get additional fields input
const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject;
const data: IDataObject = {
email,
};

Object.assign(data, additionalFields);

// Make HTTP request as defined in https://sendgrid.com/docs/api-reference/
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);
}
}
// Map data to n8n data
return [this.helpers.returnJsonArray(responseData)];
}
}

在声明式风格中:

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

// Create the FriendGrid class
export class FriendGrid implements INodeType {
description: INodeTypeDescription = {
displayName: 'FriendGrid',
name: 'friendGrid',
. . .
// Set up the basic request configuration
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: 'Create a contact',
// Add the routing object
routing: {
request: {
method: 'POST',
url: '=/contacts',
send: {
type: 'body',
properties: {
email: {{$parameter["email"]}}
}
}
}
},
// Handle the response to contact creation
output: {
postReceive: [
{
type: 'set',
properties: {
value: '={{ { "success": $response } }}'
}
}
]
}
},
],
default: 'create',
description: 'The operation to perform.',
},
{
displayName: 'Email',
. . .
},
{
displayName: 'Additional Fields',
// Sets up optional fields
},
],
}
// No execute method needed
}