Skip to content

Best practices

Iván Ovejero edited this page Jul 2, 2020 · 28 revisions

Table of Contents:


Nodes

Node description

A Node is a class that implements the interface INodeType. Most often, the class has a field called description and a method called execute() (for an execution node) or trigger() (for a trigger node). The class field is of type INodeTypeDescription, basically an object containing the following properties:

Property Notes
displayName User-facing name of the service, capitalized as in original.
name Internal reference of the node, in camelCase.
group ['transform'] (execute node) or ['trigger'] (trigger node)
defaults Object with name (same as displayName) and color (hexadecimal color code for border)
icon 'file:myNodeFile.png' (file in same dir as node)
inputs ['main'] → always
outputs ['main'] → always
version 1 → always
subtitle '={{$parameter["operation"] + ": " + $parameter["resource"]}}' (REST API)
properties See below.

Node properties

Node properties can be used for resources, operations and fields of those resources based on the operation.

Property Notes
displayName User-facing name of the property, with each initial in uppercase.
name Internal reference of the property, in camelCase.
type string, number, boolean, collection, fixedCollection, options, multiOptions
options Array of options (*) for type collection, fixedCollection, options, multiOptions
default Default value of the property.
placeholder Text to display before a value is entered in a field.
displayOptions Object containing logic for when to show the property. See below.

(*) In each option, description is a normal sentence, with only the first letter in uppercase. Remember to fill in each description in each of the node's properties.

  • Each resource display name and name should be singular.
  • The name property should be the displayName but in camelCase.
  • Operations and Resources should be ordered alphabetically.
  • The value in options can be in camelCase or snake_case.

type

Node logic

  • If the node consumes data from a REST API, structure the node using resources and operations. The operation should be named Get, Get All, Create, Delete, etc. The operation should not be named Get [resource name], but simply Get.

  • If the operation returns more than one item, the UI should have two extra fields: Return All and Limit. Return All should always be placed above Limit, and Limit should disappear when returnAll is turned on.

  • Do not use variables to set endpoints. It makes the code less readable.

  • If the operation returns more than one item, make sure the items are returned in an array:
if (Array.isArray(responseData)) {
    returnData.push.apply(returnData, responseData as IDataObject[]);
} else {
    returnData.push(responseData as IDataObject);
}
  • If the result is empty from a POST, PATCH, UPDATE, PUT request, return [{ success: true }]. If it is empty from a GET request, return [{}].

  • If a field is not required for making an API call, add the field under additionalFields.

  • Don't add the read-only fields as parameters from the API call to the node fields. For instance, Zoom API don't add the parent parameter.

  • If the operation returns a large amount of data, add in additionalFields a switch called 'Include [data items]' and set it to false by default. When it is set to false, the large data items must be deleted before returning the data.

Node Formatting

  • It is best to separate the operation/field descriptions from the node file to reduce file size. This Google Calendar node is a good reference for file structure.
  • Format your code based on the editorconfig guidelines. In VSCode you can use the EditorConfig extension, which enforces some (not all) of the rules. (For example, it enforces indent style and final newline insertion, but it does not enforce conversion of double quotes into single quotes. We might need a Prettier config to enforce the ones missing.)
root = true

[*]
charset = utf-8
indent_style = tab
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[package.json]
indent_style = space
indent_size = 2

[*.ts]
quote_type = single
  • Mimic the staggered-lines style you see in the codebase. Mind the trailing comma.
displayOptions: {
	show: {
		resource: [
			'asteroidNeoLookup',
		],
		operation: [
			'get',
		],
	},
},
  • Use the property-value shorthand.
const options: OptionsWithUri = {
    method, // not `method: method`
    qs, // not `qs: qs`
    uri: `http://hn.algolia.com/api/v1/${endpoint}`,
    json: true,
};
  • Lint your code by running npm run tslint in packages/nodes-base/. See the linting rules.
  • Try to make node logos big, i.e. reduce whitespace.
  • Make sure all resources and property names are camel-cased.

Committing

Before submitting your work for review by N8N, please squash your commits into a single one.

1. Start

Use git rebase -i HEAD~n. Here n is the number of commits in your feature branch, i.e. from your oldest to your own newest. This command will open your code editor, displaying those commits is oldest-to-newest order, like this:

pick f392171 My first commit
pick ba9dd9a Add some changes
pick df71a27 Add even more changes

2. Pick and squash

Change the commit list by picking your first commit and squashing the rest.

pick f392171 My first commit
squash ba9dd9a Add some changes
squash df71a27 Add even more changes

Instead of squash you can use s for short.

3. Edit

Save and close the editor tab. Git will reopen the editor for you to edit the commit message:

# This is a combination of 3 commits.
# This is the 1st commit message:

My first commit

# This is the commit message #2:

Add some changes

# This is the commit message #3:

Add even more changes 

Comment out the messages of the squashed commits by adding # to the messages of the commits you are squashing.

Then decide on the message of the single commit. If you are creating a new node, the commit message should be: :sparkles: [service name] node, as in :sparkles: Hacker News node. Check the N8N commit message emoji list.

If you need to edit the commit message again: git commit --amend -m "New commit message"

If anyone else has committed but their commits are lost through squashing, add them as a co-author.

4. Check

Save and close the editor. Git will have created a single commit containing all your changes. Check your work: git log should show a single commit authored by you, with the latest code you committed.

5. Push

Push your single commit to our fork: git push origin my-new-integration --force. If you already opened a pull request in the N8N repo, the commit will be reflected there as well.

Docs

  • Use the Twilio docs as the template.
  • For the link to the workflow, ensure that workflow is the only linked text.
  • Keep GIFs at the end.
  • In the instructions for the example workflow, do not include steps that are optional.
  • Use an empty link for the relevant node:
- [Start](../../core-nodes/Start)
- [PayPal]()
  • Use single quotes for UI sections and asterisk-italics for interactive UI elements:
In the section 'REST API apps', click on *Create app*.
  • Add a final newline to every file.