| .. | ||
| looping.md | ||
| modes.md | ||
| README.md | ||
| transforming-data.md | ||
Key concepts
To get the most out of n8n's functionalities and build powerful workflows, it's important to understand some basic concepts.
Expression
An expression is a string of characters and symbols in a programming language that represents a value depending upon its input. n8n uses expressions extensively when a node refers to another node for input.
Item
Data sent from one node to another is sent as an array of JSON objects. Each element in this collection is called an Item. A node performs its action on each item of incoming data.
Function
A function is a block of code designed to perform a certain task. In n8n, you can write custom JavaScript code snippets to add, remove, and update the data you receive from a node.
The Function and Function Item nodes are the most powerful in n8n. Both nodes work very similarly, they give you access to the incoming data and you can manipulate it. With these nodes you can implement any function you want using JavaScript code.
The code of the Function node gets executed only once. The node receives the full items (JSON and binary data) as an array and expects an array of items as a return value. The items returned can be totally different from the incoming ones. So it is not only possible to remove and edit existing items, but also to add or return totally new ones.
The code of the Function Item node gets executed once for every item. The node receives one item (just the JSON data) at a time as input. As a return value, it expects the JSON data of one single item. That makes it possible to add, remove, and edit JSON properties of items, but it is not possible to add new or remove existing items. Accessing and changing binary data is only possible via the methods getBinaryData and setBinaryData.
Both the Function node and Function Item node support promises. So instead of returning the item or items directly, it is also possible to return a promise which resolves accordingly.
Here is a comparative overview of the Function and Function Item nodes:
| Data to access | Function | FunctionItem |
|---|---|---|
| JSON data | items[index].json | item |
| Binary data | items[index].binary | getBinaryData() |
Data
Data represents units of information that are collected by and transmitted through nodes. For "basic usage" it is not necessarily needed to understand how the data that gets passed from one node to another is structured. However, it becomes important if you want to:
- Create your own node
- Write custom expressions
- Use the Function or Function Item node
Data structure
In n8n, all data passed between nodes is an array of objects. It has the following structure:
[
{
// For most data:
// Wrap each item in another object, with the key 'json'
"json": {
// Example data
"jsonKeyName": "keyValue",
"anotherJsonKey": {
"lowerLevelJsonKey": 1
}
},
// For binary data:
// Wrap each item in another object, with the key 'binary'
"binary": {
// Example data
"binaryKeyName": {
"data": "....", // Base64 encoded binary data (required)
"mimeType": "image/png", // Best practice to set if possible (optional)
"fileExtension": "png", // Best practice to set if possible (optional)
"fileName": "example.png", // Best practice to set if possible (optional)
}
}
},
...
]
::: tip Skipping the 'json' key and array syntax
From 0.166.0 onwards, n8n automatically adds the json key if it is missing. It also automatically wraps your items in an array ([]) if needed.
:::
Data flow
Nodes do not only process one "item", they process multiple ones.
For example, if the Trello node is set to Create-Card and it has an expression set for Name to be set depending on name property, it will create a card for each item, always choosing the name-property-value of the current one.
This data would, for example, create two cards. One named test1 the other one named test2:
[
{
name: "test1"
},
{
name: "test2"
}
]
Error workflow
For each workflow, an optional Error Workflow can be set in the Workflow Settings. It gets executed if the original execution fails. That makes it possible to, for instance, inform the user via Email or Slack if something goes wrong. The same Error Workflow can be set on multiple workflows.
The only difference between a regular workflow and an Error Workflow is that it contains an Error Trigger node, so it is important to make sure that this node gets created before setting a workflow as Error Workflow.
The Error Trigger node will trigger in case the execution fails and receives information about it. The data looks like this:
[
{
"execution": {
"id": "231",
"url": "https://n8n.example.com/execution/231",
"retryOf": "34",
"error": {
"message": "Example Error Message",
"stack": "Stacktrace"
},
"lastNodeExecuted": "Node With Error",
"mode": "manual"
},
"workflow": {
"id": "1",
"name": "Example Workflow"
}
}
]
All information is always present except:
- execution.id: Only present when the execution gets saved in the database
- execution.url: Only present when the execution gets saved in the database
- execution.retryOf: Only present when the execution is a retry of a previously failed execution
Security
By default, n8n can be accessed by everybody. This is okay if you only have it running locally but if you deploy it on a server which is accessible from the web, you have to make sure that n8n is protected.
Basic auth
Right now we have very basic protection in place using basic-auth. It can be activated by setting the following environment variables:
export N8N_BASIC_AUTH_ACTIVE=true
export N8N_BASIC_AUTH_USER=<USER>
export N8N_BASIC_AUTH_PASSWORD=<PASSWORD>
JWT
There is also limited support for JWT based authentication. If enabled, n8n will verify the token with the provided JSON Web Key Set URI. It can be configured through the following environment variables:
export N8N_JWT_AUTH_ACTIVE=true
export N8N_JWT_AUTH_HEADER=<HEADER>
export N8N_JWKS_URI=<URI>
Keep in mind that there is currently no built-in way of passing down the Token in the request, so to use JWT you have to have the token in the request manually.
