콘텐츠로 이동

05. 표현식으로 데이터 잇기

앞 노드가 만든 값을 뒤 노드가 쓰는 방법입니다. 이음새에서 가장 자주 쓰고, 가장 자주 틀리는 부분이니 이 문서만큼은 한 번 훑어두시길 권합니다.

문법은 하나입니다.

${무엇을.가져올지}

어디서 값을 가져올 수 있나

쓰는 법 가져오는 값
${nodes.<노드id>.response.body.<필드>} 앞 노드의 출력 — 가장 많이 씁니다
${nodes.<노드id>.request.data.<필드>} 그 노드가 받았던 입력
${input.<필드>} 엣지가 넘겨준 값 (조건 노드에서도 이 범위를 씁니다)
${secrets.<키>} 워크스페이스 시크릿 (API 키 등)
${vars.<키>} 워크스페이스 일반 변수
${connections.<제공사>.<필드>} 연결된 서비스의 토큰 등
${item} / ${item.<필드>} 반복 중인 현재 원소 (루프 안에서만)
${index} 반복 회차 번호 (0부터)
${datasets.<제목>.count} 데이터셋 행 개수
${datasets.<제목>.latest} 데이터셋 최근 행 전체
${datasets.<제목>.latest.<필드>} 최근 행의 특정 필드

앞 노드 출력 가져오기 (핵심)

${nodes.fetch-orders.response.body.data}
       └─ 노드 id ─┘              └ 필드 ┘

노드 id에 하이픈이 있어도 됩니다. 중첩 필드는 점으로 계속 파고들면 됩니다.

${nodes.fetch.response.body.data.customer.name}      # 중첩 객체
${nodes.fetch.response.body.items.0.name}            # 배열 첫 번째 원소 — 숫자는 인덱스
${nodes.fetch.response.body.items.2.price}           # 세 번째 원소

시크릿·변수 가져오기

apiKey: "${secrets.OPENAI_API_KEY}"     # 민감한 값
uri: "${vars.API_BASE_URL}/orders"      # 일반 설정값

시크릿과 일반 변수는 서로 접근할 수 없습니다. ${vars.*}로 시크릿을 꺼낼 수 없고 그 반대도 안 됩니다. → 08. 변수와 시크릿


| raw — 구조를 그대로 넘기기

이음새에서 가장 흔한 실수가 여기서 나옵니다. 꼭 읽어주세요.

표현식 결과는 기본적으로 문자열로 바뀝니다. 숫자나 짧은 텍스트는 문제없지만, 배열이나 객체를 다음 노드에 넘길 때는 이게 문제가 됩니다.

# ❌ 배열이 문자열로 뭉개짐
data: "${nodes.fetch-orders.response.body.data}"
# → "[{id=1, amount=1000}, {id=2, amount=2000}]" 같은 이상한 문자열이 됩니다

# ✅ 배열 그대로 전달
data: "${nodes.fetch-orders.response.body.data | raw}"

| raw가 필요한 곳

상황
Transform 노드에 데이터 넘길 때 data: "${nodes.fetch.response.body.items \| raw}"
루프에 반복할 배열 넘길 때 items: "${nodes.fetch.response.body.data \| raw}"
객체 통째로 넘길 때 payload: "${nodes.build.response.body \| raw}"

| raw의 규칙

값 전체가 표현식 하나일 때만 씁니다. 문장 중간에 끼워 넣을 수 없습니다.

# ✅ 값 전체가 표현식 하나
data: "${nodes.fetch.response.body.items | raw}"

# ❌ 문장 안에 섞음 — 동작하지 않습니다
text: "주문 목록: ${nodes.fetch.response.body.items | raw}"

문장 안에 넣고 싶다면 그건 애초에 문자열이어야 하는 값입니다. | raw 없이 쓰세요.


객체를 입력으로 넘기는 두 가지 방법

방법 1 — 구조를 직접 적고 값만 표현식으로 (권장)

input:
  body:
    orderId: "${nodes.trigger.response.body.orderId}"
    amount: "${nodes.aggregate.response.body.총액}"
    status: "confirmed"

방법 2 — 통째로 | raw

input:
  body: "${nodes.build-payload.response.body | raw}"

객체를 | raw 없이 통째로 넘기는 것만 피하면 됩니다.


엣지 매핑 vs 직접 참조

같은 일을 하는 두 가지 스타일이 있습니다. 하나를 골라 일관되게 쓰세요.

스타일 A — 직접 참조 (간단)

nodes:
  - id: notify
    type: CALL
    integration: http_request
    input:
      body:
        orderId: "${nodes.trigger.response.body.orderId}"

edges:
  - from: trigger
    to: notify

노드가 "어디서 오는 값인지"까지 직접 압니다. 짧고 읽기 쉽습니다.

스타일 B — 엣지 매핑 + ${input.*}

nodes:
  - id: notify
    type: CALL
    integration: http_request
    input:
      body:
        orderId: "${input.orderId}"

edges:
  - from: trigger
    to: notify
    request:
      data:
        orderId: "${nodes.trigger.response.body.orderId}"

노드는 "orderId가 필요하다"만 알고, 그 값을 어디서 가져올지는 선이 압니다.

언제 B를 써야 하나

조건 노드(CONDITIONAL)로 이어질 때는 B가 필수입니다. 조건식은 ${input.*} 범위에서 평가되므로, 엣지로 값을 넘겨주지 않으면 조건이 아무것도 못 봅니다. → 06. 흐름 제어


자주 겪는 문제

표현식이 그대로 문자로 나와요

${...} 안의 경로가 틀렸을 때 실행이 ExpressionResolveException으로 실패합니다. 실행 이력에서 그 노드를 열고 바로 앞 노드의 실제 출력을 확인한 뒤 경로를 맞추세요.

표현식은 저장할 때 검사하지 않습니다. 실행할 때 비로소 확인됩니다. GUI에서 중간중간 저장할 수 있도록 일부러 이렇게 되어 있습니다.

JOINT 노드 값을 가져올 수 없어요

JOINT자기 출력이 없습니다. 합류만 시키는 노드입니다. JOINT 다음 노드에서는 JOINT 이전 노드를 직접 참조하세요.

# ❌ JOINT는 출력이 없음
${nodes.join.response.body.value}

# ✅ JOINT 앞 노드를 직접 참조
${nodes.fetch-a.response.body.value}

{{ }} 는 표현식이 아닙니다

{{key}}레시피 기능의 자리표시자입니다. 직접 작성하는 워크플로우 YAML에는 절대 넣지 마세요. 표현식은 언제나 중괄호 하나 + $${...} 입니다.

스케줄 트리거인데 windowStart가 없어요

lookback을 설정해야만 생깁니다. → 03. 트리거 설정하기


빠른 참조표

# 앞 노드 출력
${nodes.fetch.response.body.data}
${nodes.fetch.response.body.items.0.name}     # 배열 인덱스
${nodes.fetch.response.body.data | raw}       # 구조 보존

# 트리거
${nodes.trigger.response.body.orderId}        # 웹훅 본문
${nodes.trigger.response.body.windowStart}    # 스케줄 lookback

# 워크스페이스 자원
${secrets.MY_API_KEY}
${vars.BASE_URL}
${connections.slack.accessToken}
${datasets.처리이력.count}
${datasets.처리이력.latest.주문번호}

# 엣지가 넘긴 값 / 조건식
${input.orderId}

# 루프 안
${item}
${item.orderId}
${index}

다음06. 흐름 제어