n8n JSON 데이터 구조 이해와 워크플로우 오류 해결법

n8n JSON 데이터 구조 이해가 부족하면, 워크플로우는 언젠가 꼭 이상하게 꼬이게 됩니다. n8n을 사용하다 보면 노드 결과 미리보기에서 데이터 구조가 계속 바뀌거나, If나 Set 노드에서 분명히 있는 데이터인데도 undefined 오류가 발생해 답답했던 경험, 한 번쯤 있으실 겁니다. 이런 문제의 90%는 n8n이 데이터를 처리하는 핵심 방식, 즉 JSON 구조에 대한 이해 부족에서 시작됩니다. 이 글을 통해 더 이상 데이터 구조 때문에 워크플로우가 멈추는 일이 없도록 만들어 드리겠습니다.

목차

1. 서론: n8n 워크플로우 자동화에서 JSON이 중요한 이유

n8n은 수많은 애플리케이션과 서비스를 연결해주는 강력한 자동화 도구입니다. 이 모든 연결의 중심에는 데이터가 있으며, n8n은 이 데이터를 ‘JSON’이라는 표준 형식으로 주고받습니다. 마치 전 세계 사람들이 영어를 공용어로 사용해 소통하듯, n8n의 모든 노드들은 JSON이라는 언어로 대화하는 셈입니다. 이 표준화된 데이터 구조 덕분에 어떤 노드에서든 일관된 방식으로 데이터를 추출, 변환, 적재(ETL)하는 작업이 가능해집니다.

1.1 JSON을 모를 때 발생하는 대표적인 문제들

만약 JSON 데이터 구조를 제대로 이해하지 못하면, 다음과 같은 흔한 문제들을 계속해서 겪게 됩니다.

  • 데이터 증발 현상: 워크플로우 중간에 데이터가 갑자기 사라진 것처럼 보이지만, 실제로는 items.json.data와 같이 한 단계 더 깊은 곳에 있는 데이터를 잘못 참조한 경우가 대부분입니다.
  • 노드 실행 오류: 외부 API에서 받은 데이터 구조가 매번 조금씩 달라져, 후속 노드들이 데이터를 제대로 찾지 못하고 오류를 일으킵니다.
  • 반복 및 조건 처리 실패: Merge, If, Loop Over Items 같은 노드에서 단 하나의 데이터(Single Item)와 여러 데이터 묶음(Array)의 차이를 구분하지 못해 워크플로우가 멈추거나 오작동합니다.

이 글에서는 n8n의 기본 데이터 구조부터 시작해, 실제 워크플로우에서 데이터를 자유자재로 다루는 실전 접근법, 그리고 JSON 데이터를 파싱하고 변환하는 기초 방법까지 체계적으로 알려드립니다. 이 글을 끝까지 읽고 나면, 어떤 노드에서 어떤 데이터가 들어오고 나가는지 머릿속으로 명확하게 그릴 수 있게 될 것입니다.

n8n 워크플로우와 JSON 데이터 구조를 보여주는 복잡한 자동화 인터페이스 이미지

2. n8n의 JSON 데이터 구조 기본 개념

n8n에서 JSON 데이터 다루기의 첫걸음은 n8n의 기본 데이터 단위를 이해하는 것입니다. 가장 중요한 핵심은 ‘n8n의 모든 데이터는 items라는 배열(Array) 안에 json 객체(Object)가 담긴 형태’라는 점입니다. 각 노드는 이 items 배열을 입력으로 받아, 배열 안의 아이템 개수만큼 실행됩니다. 예를 들어 items 배열 안에 아이템이 5개 있다면, 해당 노드는 5번 실행됩니다.

2.1 n8n 데이터의 기본 구조

n8n의 한 아이템은 다음과 같은 세 가지 주요 속성으로 구성됩니다.


[
  {
    "json": { ... },
    "binary": { ... },
    "pairedItems": [ ... ]
  }
]
  • json: 우리가 워크플로우에서 실제로 다루는 대부분의 텍스트, 숫자, 중첩된 데이터가 이곳에 객체 형태로 저장됩니다.
  • binary: 이미지, PDF, 파일 등 바이너리 데이터와 관련된 정보가 담깁니다.
  • pairedItems: 현재 아이템이 이전 노드의 어떤 아이템과 연결되는지 추적하기 위한 메타 정보입니다.

이 구조를 엑셀 시트에 비유하면 쉽게 이해할 수 있습니다. items 배열은 전체 시트, 하나의 아이템({json: {...}})은 행(Row), 그리고 json 객체 안의 각 키(key)는 열(Header)에 해당한다고 생각하면 편리합니다.

2.2 실제 데이터 예시

워크플로우에서 데이터가 어떻게 보이는지 실제 예시를 통해 확인해 보겠습니다.

– 단일 아이템 예제

하나의 데이터만 처리될 때의 모습입니다. items 배열 안에 객체가 하나만 있습니다.


[
  {
    "json": {
      "id": 1,
      "name": "John Doe",
      "email": "john@example.com"
    }
  }
]

– 다중 아이템 예제

여러 개의 데이터를 한 번에 처리할 때의 모습입니다. items 배열 안에 여러 개의 객체가 포함됩니다.


[
  { "json": { "id": 1, "name": "John" } },
  { "json": { "id": 2, "name": "Jane" } }
]

– 중첩 JSON 예제

json 객체 안에 또 다른 객체가 포함된 구조입니다. API 응답 데이터에서 흔히 볼 수 있습니다.


[
  {
    "json": {
      "id": 1,
      "name": "John",
      "address": {
        "city": "Seoul",
        "zip": "12345"
      }
    }
  }
]
엑셀 시트로 비유한 n8n JSON 데이터 구조 이미지

3. n8n에서 JSON 데이터 다루기: 실전 접근법

기본 구조를 이해했다면 이제 데이터를 실제로 참조하고 가공하는 방법을 알아볼 차례입니다. n8n에서는 표현식(Expressions)을 사용해 데이터에 쉽게 접근할 수 있습니다.

3.1 표현식을 이용한 데이터 접근 및 참조

표현식은 {{ }} 안에 작성하며, 워크플로우의 거의 모든 입력 필드에서 사용할 수 있습니다.

  • $json: 현재 노드에서 처리 중인 아이템의 json 객체에 직접 접근합니다. 가장 기본적이고 많이 사용됩니다.
    예: {{ $json.name }}, {{ $json.address.city }}
  • $node[]: 특정 이전 노드의 결과 데이터에 접근합니다. 워크플로우의 다른 부분에서 데이터를 가져와야 할 때 유용합니다.
    예: {{ $node["HTTP Request"].json.data }} (HTTP Request 노드의 첫 번째 아이템의 json 객체 안의 data 키 값)
  • $input: 현재 노드로 들어오는 전체 입력 데이터를 가리킵니다. 주로 Code 노드에서 여러 아이템을 한 번에 처리할 때 사용합니다.
    예: {{ $input.first().json }} (입력된 첫 번째 아이템의 json 객체), {{ $input.all() }} (입력된 모든 아이템 배열)

예를 들어, “외부 API에서 사용자 목록을 받아와 첫 번째 사용자의 이메일만 슬랙으로 보내기” 같은 작업은 Set 노드에서 {{ $node['HTTP Request'].json[0].email }} 과 같은 표현식으로 간단하게 처리할 수 있습니다.

3.2 주요 노드별 JSON 데이터 처리 방법

각 노드는 저마다의 방식으로 JSON 데이터를 처리합니다. 자주 사용하는 노드들의 데이터 처리법을 알아두면 워크플로우 설계가 훨씬 쉬워집니다.

– Set / Edit Fields 노드

데이터를 추가, 수정, 삭제하는 가장 기본적인 노드입니다. ‘Expression’ 토글을 활성화하면 표현식을 사용해 동적인 데이터를 만들 수 있습니다.
예: fullName이라는 새 필드를 만들고, 값에 {{ $json.firstName + ' ' + $json.lastName }}를 입력해 이름 합치기

– Code 노드

자바스크립트로 복잡한 데이터 변환을 처리할 때 사용합니다. 간단한 데이터 조작은 Set 노드가 편리하지만, 여러 아이템을 종합하거나 복잡한 로직이 필요할 땐 Code 노드가 필수적입니다. $input.all()로 모든 아이템을 받아와 map, filter 같은 배열 함수로 처리하고, 새로운 items 배열을 반환하는 패턴이 주로 사용됩니다.

– If / Filter 노드

데이터의 특정 값에 따라 워크플로우를 분기시키는 노드입니다. ‘Expression’ 탭에서 {{ $json.age > 30 }} 과 같은 조건식을 사용해 true 또는 false를 반환하게 만들어 데이터 흐름을 제어합니다.

– Merge 노드

여러 경로로 나뉜 데이터 흐름을 하나로 합칠 때 사용됩니다. 두 가지 핵심 모드의 차이를 이해하는 것이 중요합니다.

모드설명주요 사용 사례
Combine by Index (인덱스 기준 결합)두 입력(Input 1, Input 2)의 아이템 순서를 기준으로 데이터를 합칩니다. 첫 번째 아이템은 첫 번째 아이템끼리, 두 번째는 두 번째끼리 합쳐집니다.순서가 중요한 데이터를 병렬 처리한 후 다시 합칠 때 사용합니다.
Merge by Key (키 기준 결합)지정한 키(Key)의 값이 같은 아이템끼리 데이터를 합칩니다. 데이터의 순서와 상관없이 고유 ID 등을 기준으로 정확하게 데이터를 병합할 수 있습니다.서로 다른 데이터 소스에서 가져온 정보를 사용자 ID나 제품 코드 같은 공통 키로 합칠 때 유용합니다.

3.3 데이터 변환 실전 패턴

Code 노드를 활용하면 거의 모든 형태의 데이터 변환이 가능합니다.

  • 배열을 개별 아이템으로 분리하기: API 응답 결과가 하나의 아이템 속 배열로 들어올 때, 각 배열 요소를 별개의 n8n 아이템으로 만들어 줍니다.
    return $input.first().json.data.map(d => ({ json: d }));
  • 여러 아이템을 하나의 배열로 합치기: 여러 아이템을 하나의 json 객체 안의 배열 값으로 묶어야 할 때 사용합니다.
    return [{ json: { users: $input.all().map(item => item.json) } }];
  • 타입 및 날짜 변환: 문자열로 된 숫자를 실제 숫자로 바꾸거나, 날짜 형식을 표준 형식(ISO)으로 변환합니다.
    Number($json.age), new Date($json.createdAt).toISOString()
n8n 노드에서 사용하는 표현식과 데이터 접근법 예시 이미지
n8n에서 JSON 데이터를 인덱스 기준과 키 기준으로 합치는 방법 시각화 이미지

4. JSON 파싱과 변환 기초 방법

워크플로우를 만들다 보면 순수한 JSON 객체가 아닌, 문자열 형태의 JSON을 다뤄야 할 때가 있습니다. JSON 파싱과 변환 기초 방법을 알아두면 이런 상황에 유연하게 대처할 수 있습니다.

4.1 JSON 문자열 파싱하기 (Parsing)

JSON 문자열과 JSON 객체는 다릅니다. 문자열은 그냥 텍스트 덩어리("{\"name\":\"John\"}")라서 .name과 같이 속성에 접근할 수 없습니다. 이를 접근 가능한 객체({ "name": "John" })로 바꾸는 과정을 ‘파싱(Parsing)’이라고 합니다.

Code 노드에서 JSON.parse() 함수를 사용하면 됩니다. 잘못된 형식의 문자열 때문에 워크플로우 전체가 멈추는 것을 방지하기 위해 try...catch 구문으로 감싸주는 것이 안전합니다.


const items = $input.all();

for (const item of items) {
  try {
    item.json.parsedBody = JSON.parse(item.json.body);
  } catch (error) {
    item.json.parseError = error.message;
  }
}

return items;

참고로 HTTP Request나 Webhook 같은 노드들은 응답 데이터를 자동으로 JSON 객체로 파싱해주는 옵션을 제공하므로, 대부분의 경우 직접 파싱할 필요는 없습니다.

4.2 JSON 데이터 문자열화하기 (Stringifying)

반대로, JSON 객체를 다른 API로 보낼 때 순수한 문자열 형태로 바꿔야 하는 경우가 있습니다. 이 과정을 ‘문자열화(Stringifying)’ 또는 ‘직렬화(Serialization)’라고 부릅니다.

Code 노드에서 JSON.stringify() 함수를 사용해 간단히 변환할 수 있습니다.


const dataToSend = $json.data;
const bodyAsString = JSON.stringify(dataToSend);

return [{ json: { body: bodyAsString } }];

이렇게 생성된 문자열을 HTTP Request 노드의 ‘Body’에 넣고, 헤더의 Content-Typeapplication/json으로 설정해 API 요청을 보내는 것이 일반적인 패턴입니다.

n8n Code 노드에서 JSON 문자열 파싱과 문자열화 과정을 보여주는 이미지

5. 고급 테크닉 & 베스트 프랙티스

기본기를 다졌다면, 이제 워크플로우를 더 안정적이고 관리하기 쉽게 만들어주는 몇 가지 고급 전략을 알아봅시다.

  • 표준 데이터 스키마 만들기: 여러 다른 API에서 데이터를 가져올 때, 각기 다른 필드 이름을 가질 수 있습니다. Code 노드나 Set 노드를 워크플로우 초반에 배치하여 모든 데이터를 { id, name, value } 와 같은 일관된 공통 구조로 맞춰주면, 후속 노드들을 훨씬 간단하게 관리할 수 있습니다.
  • 에러 핸들링을 위한 구조 설계: 데이터 처리 중 문제가 발생했을 때를 대비해 error, raw, meta 같은 필드를 json 객체에 추가하는 패턴을 사용하면 좋습니다. 이렇게 하면 에러 발생 시 원본 데이터(raw)와 에러 메시지(error)를 함께 로깅하기 편리합니다.
  • 가독성을 위한 노드 선택: 간단한 필드 추가나 수정은 Code 노드보다 Set, If, Item Lists 같은 기본 노드를 사용하는 것이 좋습니다. Code 노드는 강력하지만, 코드가 길어지면 다른 사람이 워크플로우를 이해하기 어려워집니다. 꼭 필요한 복잡한 로직에만 Code 노드를 사용하는 것이 유지보수 측면에서 유리합니다.
  • 중첩 구조 평탄화: $json.data.user.profile.address처럼 데이터 구조가 너무 깊어지면 표현식이 길고 복잡해집니다. 중간에 Set 노드를 사용해 자주 쓰는 값을 $json.userAddress 와 같이 상위 레벨로 한번 꺼내주면, 이후의 작업이 훨씬 깔끔해집니다.
n8n 워크플로우 고급 전략과 베스트 프랙티스를 보여주는 작업 공간 이미지

6. 마무리 및 다음 단계 제안

이 글을 통해 n8n에서 데이터를 다루는 핵심 원리를 살펴보았습니다. 이제 여러분은 n8n의 데이터가 어떻게 흐르는지, 그리고 어떻게 원하는 대로 가공할 수 있는지에 대한 자신감을 얻으셨을 겁니다.

핵심 개념을 다시 한번 정리해 보겠습니다.

  • n8n의 데이터는 항상 items 배열 구조를 가집니다.
  • 아이템은 json, binary, pairedItems로 구성되며, 우리는 주로 json 객체를 다룹니다.
  • $json, $node[], $input` 같은 표현식으로 데이터에 자유롭게 접근할 수 있습니다.
  • JSON 문자열과 객체의 차이를 이해하고 JSON.parse()JSON.stringify()를 적절히 사용해야 합니다.

오늘 배운 내용을 바탕으로 기존에 만들었던 워크플로우를 다시 한번 살펴보세요. 불필요하게 복잡했던 데이터 처리 과정을 더 단순하고 명확하게 개선할 수 있는 부분이 분명 보일 것입니다. n8n의 진정한 힘은 바로 이 데이터 흐름을 완벽하게 제어하는 데서 나옵니다.

다음 학습 주제 제안:

  • n8n에서 에러 핸들링 및 로깅 구조 설계하기
  • 실무 예제로 보는 n8n 데이터 변환 고급 패턴 모음
n8n 데이터 흐름과 핵심 개념을 요약하는 시각적 이미지

자주 묻는 질문 (FAQ)

Q: n8n에서 items 배열이 비어있는 경우는 왜 발생하나요?

A: 이전 노드에서 아무런 결과를 반환하지 않았거나, If/Filter 노드에서 모든 데이터가 필터링되었을 수 있습니다. 또는, Code 노드에서 return []; 과 같이 빈 배열을 명시적으로 반환한 경우에도 발생합니다.

Q: {{ $json.data }}{{ $node['Node Name'].json.data }}의 차이점은 무엇인가요?

A: {{ $json.data }}는 현재 노드가 처리하고 있는 개별 아이템json 객체 내 data 키를 참조합니다. 반면 {{ $node['Node Name'].json.data }}는 ‘Node Name’이라는 특정 이전 노드첫 번째 아이템json 객체 내 data 키를 참조합니다. 워크플로우의 다른 부분에서 데이터를 가져올 때는 $node를 사용해야 합니다.

Q: Code 노드와 Set 노드 중 어떤 것을 사용해야 할까요?

A: 간단한 값 할당, 필드 추가/수정, 이름 합치기 등은 Set 노드가 직관적이고 편리합니다. 반면, 여러 아이템의 데이터를 종합(집계)하거나, 복잡한 조건문/반복문이 필요하거나, 외부 라이브러리를 사용해야 하는 등 복잡한 데이터 변환이 필요할 때는 Code 노드를 사용하는 것이 적합합니다.

참고할 페이지: n8n 노드 종류 및 기능 완벽 가이드와 실습 예제

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

이 글이 마음에 드세요?

RSS 피드를 구독하세요!

댓글 남기기