콘텐츠로 이동
📣 인포그랩에서 OpenAI 기술 기반으로 자체 개발한 자동화 번역 프로그램을 통해 n8n 공식 문서의 한글판을 국내 최초로 제공합니다.

선언형 스타일 노드 만들기#

이 튜토리얼은 선언형 스타일 노드를 만드는 과정을 안내합니다. 시작하기 전에, 이것이 필요한 노드 스타일인지 확인하세요. 자세한 내용은 노드 빌딩 접근 방식 선택하기를 참조하세요.

전제 조건#

다음이 개발 머신에 설치되어 있어야 합니다:

  • git
  • Node.js 및 npm. 최소 요구 버전: Node 18.17.0.
  • Linux, Mac, WSL에서 nvm(Node Version Manager)을 사용하여 설치하는 방법은 여기를 참고하세요.
  • Windows 사용자는 Microsoft의 Windows에서 NodeJS 설치 가이드를 참고하세요.

다음에 대한 약간의 이해가 필요합니다:

  • JavaScript/TypeScript
  • REST APIs
  • git

노드 만들기#

이 섹션에서는 n8n의 노드 스타터 리포지토리를 클론하고 NASA API와 통합된 노드를 만듭니다. APOD(오늘의 천문 사진)와 Mars Rover Photos의 NASA 서비스 두 가지를 사용하는 노드를 생성할 것입니다. 코드 예제를 짧게 유지하기 위해, 노드는 Mars Rover Photos 엔드포인트에 대한 모든 사용 가능한 옵션을 구현하지 않습니다.

기존 노드

n8n에는 내장된 NASA 노드가 있습니다. 기존 노드와 충돌을 피하기 위해, 버전의 이름을 다르게 지정할 것입니다.

1단계: 프로젝트 설정#

n8n은 노드 개발을 위한 스타터 리포지토리를 제공합니다. 스타터를 사용하면 필요한 모든 종속성이 포함됩니다. 또한 린터를 제공합니다.

리포지토리를 클론하고 디렉토리로 이동합니다:

  1. 템플릿 리포지토리에서 새 리포지토리 생성하기.
  2. 새 리포지토리를 클론합니다:
    1
    2
    git clone https://github.com/<your-organization>/<your-repo-name>.git n8n-nodes-nasa-pics
    cd n8n-nodes-nasa-pics
    

스타터에는 예제 노드와 자격 증명이 포함되어 있습니다. 다음 디렉토리와 파일을 삭제합니다:

  • nodes/ExampleNode
  • nodes/HTTPBin
  • credentials/ExampleCredentials.credentials.ts
  • credentials/HttpBinApi.credentials.ts

이제 다음 디렉토리와 파일을 생성합니다:

nodes/NasaPics
nodes/NasaPics/NasaPics.node.json
nodes/NasaPics/NasaPics.node.ts
credentials/NasaPicsApi.credentials.ts

이들은 모든 노드를 위한 핵심 파일입니다. 필수 파일과 권장되는 조직에 대한 더 많은 정보는 노드 파일 구조를 참조하세요.

이제 프로젝트 종속성을 설치합니다:

1
npm i

2단계: 아이콘 추가#

여기에서 NASA SVG 로고를 다운로드하여 nodes/NasaPics/nasapics.svg로 저장합니다.

n8n에서는 SVG 형식의 아이콘 사용을 권장하지만, PNG 형식도 사용할 수 있습니다.
PNG를 사용할 경우 해상도는 60x60px 이어야 하며,
노드 아이콘은 정사각형 또는 정사각형에 가까운 비율을 유지해야 합니다.

Font Awesome 아이콘을 직접 참조하지 마세요

Font Awesome 아이콘을 사용하려면, 아이콘을 다운로드하여 직접 삽입해야 합니다.

3단계: 노드 생성#

모든 노드는 기본 파일이 있어야 합니다. 기본 파일 매개변수에 대한 자세한 내용은 노드 기본 파일을 참조하세요.

이 예제에서 파일은 NasaPics.node.ts입니다. 이 튜토리얼을 짧게 유지하기 위해, 모든 노드 기능을 이 파일 하나에 배치할 것입니다. 더 복잡한 노드를 빌드할 때는 기능을 모듈로 나누는 것을 고려해야 합니다. 필수 파일과 권장되는 조직에 대한 더 많은 정보는 노드 파일 구조를 참조하세요.

Step 3.1: Imports#

먼저 import 문을 추가하세요:

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

Step 3.2: 메인 클래스 생성#

노드는 INodeType을 구현하는 인터페이스를 내보내야 합니다. 이 인터페이스는 description 인터페이스를 포함해야 하며, 이 인터페이스는 properties 배열을 포함해야 합니다.

클래스 이름 및 파일 이름

클래스 이름과 파일 이름이 일치하는지 확인하세요. 예를 들어, 클래스 NasaPics가 주어지면 파일 이름은 NasaPics.node.ts여야 합니다.

1
2
3
4
5
6
7
8
export class NasaPics implements INodeType {
	description: INodeTypeDescription = {
		// 기본 노드 세부 정보는 여기로 들어갑니다
		properties: [
		// 리소스 및 작업은 여기로 들어갑니다
		]
	};
}

Step 3.3: 노드 세부정보 추가#

모든 노드는 표시 이름, 아이콘 및 노드를 사용하여 요청을 생성하기 위한 기본 정보와 같은 기본 매개변수가 필요합니다. description에 다음을 추가하세요:

 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
displayName: 'NASA Pics',
name: 'NasaPics',
icon: 'file:nasapics.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'NASA의 API로부터 데이터 가져오기',
defaults: {
	name: 'NASA Pics',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
	{
		name: 'NasaPicsApi',
		required: true,
	},
],
requestDefaults: {
	baseURL: 'https://api.nasa.gov',
	headers: {
		Accept: 'application/json',
		'Content-Type': 'application/json',
	},
},

n8n은 description에 설정된 일부 속성을 사용하여 편집기 UI에서 노드를 렌더링합니다. 이 속성은 displayName, icon, descriptionsubtitle입니다.

Step 3.4: 리소스 추가#

리소스 객체는 노드가 사용하는 API 리소스를 정의합니다. 이 튜토리얼에서는 NASA의 두 API 엔드포인트인 planetary/apodmars-photos에 접근하는 노드를 생성하고 있습니다. 즉, NasaPics.node.ts에서 두 개의 리소스 옵션을 정의해야 합니다. 리소스 객체와 함께 properties 배열을 업데이트하세요:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
properties: [
	{
		displayName: 'Resource',
		name: 'resource',
		type: 'options',
		noDataExpression: true,
		options: [
			{
				name: '오늘의 천문학 사진',
				value: 'astronomyPictureOfTheDay',
			},
			{
				name: '화성 탐사 로버 사진',
				value: 'marsRoverPhotos',
			},
		],
		default: 'astronomyPictureOfTheDay',
	},
	// 작업은 여기로 들어갑니다

]

type은 n8n이 리소스를 위해 어떤 UI 요소를 표시할지를 제어하며, n8n이 사용자가 어떤 유형의 데이터를 예상하는지를 알려줍니다. options는 n8n이 사용자가 하나의 옵션을 선택할 수 있도록 드롭다운을 추가하게 됩니다. 추가 정보는 Node UI elements를 참조하세요.

Step 3.5: 작업 추가#

작업 객체는 리소스에서 사용할 수 있는 작업을 정의합니다.

선언적 스타일의 노드에서는 작업 객체가 routing을 포함합니다(옵션 배열 내). 이는 API 호출의 세부 사항을 설정합니다.

properties 배열에 resource 객체 다음으로 다음을 추가하세요:

  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
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
{
	displayName: 'Operation',
	name: 'operation',
	type: 'options',
	noDataExpression: true,
	displayOptions: {
		show: {
			resource: [
				'astronomyPictureOfTheDay',
			],
		},
	},
	options: [
		{
			name: '가져오기',
			value: 'get',
			action: '오늘의 천문학 사진 가져오기',
			description: '오늘의 천문학 사진 가져오기',
			routing: {
				request: {
					method: 'GET',
					url: '/planetary/apod',
				},
			},
		},
	],
	default: 'get',
},
{
	displayName: 'Operation',
	name: 'operation',
	type: 'options',
	noDataExpression: true,
	displayOptions: {
		show: {
			resource: [
				'marsRoverPhotos',
			],
		},
	},
	options: [
		{
			name: '가져오기',
			value: 'get',
			action: '화성 탐사 로버 사진 가져오기',
			description: '화성 탐사 로버에서 사진 가져오기',
			routing: {
				request: {
					method: 'GET',
				},
			},
		},
	],
	default: 'get',
},
{
	displayName: '탐사 로버 이름',
	description: '어떤 화성 탐사 로버에서 사진을 가져올지 선택하세요',
	required: true,
	name: 'roverName',
	type: 'options',
	options: [
		{name: '큐리오시티', value: 'curiosity'},
		{name: '오포튜니티', value: 'opportunity'},
		{name: '퍼서비어런스', value: 'perseverance'},
		{name: '스피릿', value: 'spirit'},
	],
	routing: {
		request: {
			url: '=/mars-photos/api/v1/rovers/{{$value}}/photos',
		},
	},
	default: 'curiosity',
	displayOptions: {
		show: {
			resource: [
				'marsRoverPhotos',
			],
		},
	},
},
{
	displayName: '날짜',
	description: '지구 날짜',
	required: true,
	name: 'marsRoverDate',
	type: 'dateTime',
	default:'',
	displayOptions: {
		show: {
			resource: [
				'marsRoverPhotos',
			],
		},
	},
	routing: {
		request: {
			// 이미 URL을 설정했습니다. qs는 필드의 값을 쿼리 문자열로 추가합니다
			qs: {
				earth_date: '={{ new Date($value).toISOString().substr(0,10) }}',
			},
		},
	},
},
// 선택적/추가 필드는 여기로 들어갑니다

이 코드는 오늘의 APOD 이미지를 가져오는 작업과 화성 탐사 로버의 사진을 요청하는 두 가지 작업을 생성합니다. roverName이라는 객체는 사용자가 어떤 로버에서 사진을 원하는지 선택하도록 요구합니다. 화성 탐사 로버 작업의 routing 객체는 이를 참조하여 API 호출을 위한 URL을 생성합니다.

3.6단계: 선택적 필드#

이 예제에서 사용하고 있는 NASA API를 포함하여 대부분의 API에는 쿼리를 세분화하기 위해 사용할 수 있는 선택적 필드가 있습니다.

사용자를 압도하지 않기 위해 n8n은 UI에서 추가 필드 아래에 이러한 필드를 표시합니다.

이 튜토리얼에서는 사용자가 APOD 엔드포인트와 함께 사용할 날짜를 선택할 수 있도록 하나의 추가 필드를 추가합니다. 속성 배열에 다음을 추가하세요:

 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
{
	displayName: '추가 필드',
	name: 'additionalFields',
	type: 'collection',
	default: {},
	placeholder: '필드 추가',
	displayOptions: {
		show: {
			resource: [
				'astronomyPictureOfTheDay',
			],
			operation: [
				'get',
			],
		},
	},
	options: [
		{
			displayName: '날짜',
			name: 'apodDate',
			type: 'dateTime',
			default: '',
			routing: {
				request: {
					// 이미 URL을 설정했습니다. qs는 필드의 값을 쿼리 문자열로 추가합니다.
					qs: {
						date: '={{ new Date($value).toISOString().substr(0,10) }}',
					},
				},
			},
		},
	],									
}

4단계: 인증 설정#

NASA API는 사용자가 API 키로 인증해야 합니다.

다음 내용을 nasaPicsApi.credentials.ts에 추가합니다:

 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
import {
	IAuthenticateGeneric,
	ICredentialType,
	INodeProperties,
} from 'n8n-workflow';

export class NasaPicsApi implements ICredentialType {
	name = 'NasaPicsApi';
	displayName = 'NASA Pics API';
	// 이 튜토리얼의 링크를 예제로 사용합니다
	// 자신의 노드를 만들 때는 자신의 문서 링크로 교체하세요
	documentationUrl = 'https://n8n-docs.infograb.net/integrations/creating-nodes/build/declarative-style-node/';
	properties: INodeProperties[] = [
		{
			displayName: 'API 키',
			name: 'apiKey',
			type: 'string',
			default: '',
		},
	];
	authenticate = {
		type: 'generic',
		properties: {
			qs: {
				'api_key': '={{$credentials.apiKey}}'
			}
		},
	} as IAuthenticateGeneric;
}

자격증명 파일 및 옵션에 대한 자세한 내용은 Credentials file를 참조하세요.

5단계: 노드 메타데이터 추가#

노드에 대한 메타데이터는 노드의 루트에 있는 JSON 파일에 들어갑니다. n8n에서는 이를 codex 파일이라고 합니다. 이 예제에서 파일은 NasaPics.node.json입니다.

JSON 파일에 다음 코드를 추가하세요:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{
	"node": "n8n-nodes-base.NasaPics",
	"nodeVersion": "1.0",
	"codexVersion": "1.0",
	"categories": [
		"Miscellaneous"
	],
	"resources": {
		"credentialDocumentation": [
			{
				"url": ""
			}
		],
		"primaryDocumentation": [
			{
				"url": ""
			}
		]
	}
}

이러한 매개변수에 대한 자세한 내용은 Node codex files를 참조하세요.

6단계: npm 패키지 세부정보 업데이트#

당신의 npm 패키지 세부정보는 프로젝트의 루트에 있는 package.json에 있습니다. 자격 증명 및 기본 노드 파일에 대한 링크가 포함된 n8n 객체를 포함하는 것이 중요합니다. 이 파일을 다음 정보를 포함하도록 업데이트하세요:

 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
{
	// 모든 노드 이름은 "n8n-nodes-"로 시작해야 합니다.
	"name": "n8n-nodes-nasapics",
	"version": "0.1.0",
	"description": "NASA의 APOD 및 Mars Rover Photo 서비스를 호출하는 n8n 노드.",
	"keywords": [
		// 이 키워드는 커뮤니티 노드에 필요합니다.
		"n8n-community-node-package"
	],
	"license": "MIT",
	"homepage": "https://n8n.io",
	"author": {
		"name": "Test",
		"email": "test@example.com"
	},
	"repository": {
		"type": "git",
		// 자신의 리포지토리로 git 원격을 변경하세요.
		// 여기에서 새로운 URL을 추가하세요.
		"url": "git+<your-repo-url>"
	},
	"main": "index.js",
	"scripts": {
		// 변경하지 마세요
	},
	"files": [
		"dist"
	],
	// 자격 증명 및 노드 링크
	"n8n": {
		"n8nNodesApiVersion": 1,
		"credentials": [
			"dist/credentials/NasaPicsApi.credentials.js"
		],
		"nodes": [
			"dist/nodes/NasaPics/NasaPics.node.js"
		]
	},
	"devDependencies": {
		// 변경하지 마세요
	},
	"peerDependencies": {
		// 변경하지 마세요
	}
}

자신의 이름과 리포지토리 URL과 같은 정보를 포함하도록 package.json을 업데이트해야 합니다. npm package.json 파일에 대한 더 많은 정보는 npm의 package.json 문서를 참조하세요.

노드 테스트#

로컬 n8n 인스턴스에서 노드를 실행하며 테스트할 수 있습니다.

  1. n8n 설치
    1
    npm install n8n -g
    
  2. 노드를 테스트할 준비가 되면 로컬에서 빌드 및 배포하세요:
    1
    2
    3
    # 노드 디렉터리에서 실행
    npm run build
    npm link
    
  3. n8n 설치 디렉터리의 nodes 디렉터리에서 다음을 실행합니다:
    1
    2
    # 노드 패키지 이름은 package.json에 정의된 이름입니다.
    npm link <node-package-name>
    

디렉터리 확인

1
2
3
4
`npm link <node-name>` 명령을 실행할 때, n8n 설치 디렉터리 내 nodes 디렉터리에서 실행해야 합니다.

* `~/.n8n/custom/`
* `~/.n8n/<your-custom-name>`: if your n8n installation set a different name using `N8N_CUSTOM_EXTENSIONS`.
  1. n8n 시작
    1
    n8n start
    
  2. 브라우저에서 n8n을 열고, 노드 패널에서 추가한 노드를 검색하세요.

노드 이름 검색

노드를 검색할 때 패키지 이름이 아니라 노드 이름을 입력해야 합니다.

예를 들어, npm 패키지 이름이 n8n-nodes-weather-nodes이고,
이 패키지에 rain, sun, snow 노드가 포함되어 있다면,
검색 시 weather-nodes 가 아니라 rain 을 입력해야 합니다.

Troubleshooting#

  • ~/.n8n 디렉터리에 custom 폴더가 없는 경우

직접 custom 디렉터리를 생성하고 npm init을 실행하세요:

1
2
3
4
# In ~/.n8n directory run
mkdir custom 
cd custom 
npm init

다음 단계#

인포레터에서 최신 DevOps 트렌드를 격주로 만나보세요!