server-dev-blog

n8n을 API 서버처럼 쓰기 - Docker Compose로 Webhook API 만들기

n8n을 처음 접하면 보통 "Zapier 같은 거"라고 생각한다. 틀린 말은 아닌데, 그게 다가 아니다.

n8n은 이벤트 처리 런타임���자 경량 API 컴포저���. 코드 없이 Webhook을 열고, 외부 API를 호출하고, 응답을 가공해서 돌려줄 수 있다. 직접 해보면 감이 온다.


이 글에서 만드는 것

Docker Compose로 로컬에 n8n을 띄우고, 아래 워크플로우를 만든다:

클라이언트
  ↓ (Basic Auth + JSON 요청)
Webhook 노드
  ↓
HTTP Request (httpbin.org로 전달)
  ↓
Edit Fields (응답 가공)
  ↓
Respond to Webhook (클라이언트에게 응답)

최종 결과: curl로 호출하면 응답이 오는 API


1. Docker Compose로 n8n 실행하기

n8n은 Docker 이미지로 제공된다. 별도 DB 없이 SQLite만으로도 충분히 돌아간다.

docker-compose.yml

services:
  n8n:
    image: n8nio/n8n:latest
    ports:
      - "5678:5678"
    environment:
      TZ: Asia/Seoul
      N8N_HOST: localhost
      N8N_PORT: 5678
      N8N_PROTOCOL: http
      WEBHOOK_URL: http://localhost:5678
      N8N_ENCRYPTION_KEY: your-secret-key
    volumes:
      - ./n8n_data:/home/node/.n8n

왜 Postgres 없이 SQLite로?

  • 로컬 테스트용이라면 SQLite로 충분
  • 워크플로우 데이터가 n8n_data 볼륨에 저장됨
  • 나중에 프로덕션으로 옮길 때 DB 교체하면 됨

실행

docker compose up -d

http://localhost:5678 접속하면 n8n 대시보드가 뜬다.

n8n 대시보드 화면

계정 생성하고 로그인하면 이런 대시보드가 보인다. 여기서 워크플로우를 만들고 관리한다.


2. 완성된 워크플로우 미리보기

이번에 만들 워크플로우는 이렇게 생겼다:

완성된 워크플로우

노드 4개짜리 간단한 구조:

  1. Webhook - 외부 요청을 받는 진입점
  2. HTTP Request - 받은 데이터를 httpbin.org로 전달
  3. Edit Fields (Set) - 응답을 가공
  4. Respond to Webhook - 클라이언트에게 응답 반환

하나씩 설정해보자.


3. Webhook 노드 설정

Webhook 노드는 트리거이면서 동시에 API 엔드포인트���. 이게 n8n이 "자동화 도구"를 넘어서는 지점이다.

Webhook 설정창

주요 설정

항목설명
HTTP MethodPOST데이터를 받을 거니까 POST
Pathwebhook엔드포인트 경로
AuthenticationBasic Auth간단한 인증
RespondUsing 'Respond to Webhook' Node가공 후 응답

Respond 설정이 중요하다.

  • Immediately: Webhook이 받자마자 바로 응답
  • Using 'Respond to Webhook' Node: 뒤에서 가공한 후 응답

우리는 httpbin 응답을 가공해서 돌려줄 거니까 후자를 선택한다.


4. Basic Auth 인증 테스트

인증을 노드 단위로 건다는 게 포인트다. 별도 인증 서버 없이 Webhook 자체에 Basic Auth를 걸 수 있다.

Basic Auth 테스트 - 인증 없이 vs 인증 있이

  • 왼쪽: 인증 없이 호출 → 401 Unauthorized
  • 오른쪽: -u test:test로 인증 후 호출 → 정상 응답
# 인증 없이 (실패)
curl -X POST http://localhost:5678/webhook-test/webhook
 
# 인증 있이 (성공)
curl -X POST http://localhost:5678/webhook-test/webhook \
  -u test:test \
  -H "Content-Type: application/json" \
  -d '{"event": "test"}'

5. HTTP Request 노드 - 외부 API 호출

Webhook으로 받은 body를 그대로 외부 API에 전달한다. 테스트용으로 httpbin.org를 쓴다.

Webhook 성공적으로 호출됐을 때

핵심 설정

항목
MethodPOST
URLhttps://httpbin.org/post
Body Content TypeJSON
Body={{ $json.body }}

={{ $json.body }}가 핵심이다.

이 표현식이 "이전 노드의 JSON에서 body 필드를 가져와라"는 의미다. n8n에서 노드 간 데이터 전달은 이런 식으로 한다.

n8n 표현식 문법: ={{ }} vs {{ }}

헷갈리기 쉬운 부분이라 정리해둔다.

문법용도예시
={{ expression }}필드 값 전체��� 표현식일 때={{ $json.body }}
{{ expression }}문자열 안에 표현식을 삽입할 때Hello, {{ $json.name }}!

예시:

// 필드 값 전체가 동적일 때
Body: ={{ $json.body }}
 
// 문자열 중간에 값 삽입
Message: "User {{ $json.userId }} logged in at {{ $json.timestamp }}"
 
// URL에 파라미터 삽입
URL: https://api.example.com/users/{{ $json.id }}

= 기호가 있으면 "이 필드는 표현식이다"라고 n8n에 알려주는 거다. 없으면 문자열 템플릿으로 처리된다.

스크린샷을 보면 Webhook에서 받은 데이터가 HTTP Request 노드로 잘 전달된 걸 확인할 수 있다.


6. Edit Fields (Set) 노드 - 응답 가공

HTTP Request의 응답을 그대로 돌려줘도 되지만, 보통은 가공이 필요하다.

Edit Fields (Set) 설정

설정 예시

필드설명
trackedtrue고정값
echo={{ $json.json }}httpbin이 돌려준 JSON

응답 스키마를 명시적으로 정의하는 거다. 클라이언트가 받을 JSON 구조:

{
  "tracked": true,
  "echo": { ... }
}

7. Respond to Webhook 노드

마지막 노드다. Edit Fields에서 가공한 데이터를 클라이언트에게 응답으로 보낸다.

Respond to Webhook 설정

설정

항목
Respond WithAll Incoming Items

별거 없다. 이전 노드에서 만든 데이터를 그대로 응답으로 보내면 된다.

주의할 점: 이 노드는 "Execute Step" 버튼으로 테스트가 안 된다. Webhook이 실제 HTTP 요청을 받아야 전체 플로우가 실행되기 때문이다.


8. 전체 워크플로우 테스트

모든 노드 설정이 끝나면 워크플로우를 실행해보자.

모든 워크플로우가 성공했을 때

각 노드에 초록색 체크가 뜨면 성공이다. 왼쪽에서 오른쪽으로 데이터가 흘러가는 걸 확인할 수 있다:

  1. Webhook이 요청을 받음
  2. HTTP Request가 httpbin에 전달
  3. Edit Fields가 응답을 가공
  4. Respond to Webhook이 클라이언트에게 반환

9. curl로 최종 테스트

실제로 curl로 호출해서 응답을 확인해보자.

curl 요청과 응답

curl -X POST http://localhost:5678/webhook-test/webhook \
  -u test:test \
  -H "Content-Type: application/json" \
  -d '{"userId": "user123", "event": "page_view"}'

응답:

{
  "tracked": true,
  "echo": {
    "userId": "user123",
    "event": "page_view"
  }
}

끝. n8n으로 API 하나를 만들었다.


프로덕션 URL

테스트가 끝나면 워크플로우를 Active 상태로 바꾼다. 그러면 URL이 바뀐다:

테스트: http://localhost:5678/webhook-test/webhook
운영:   http://localhost:5678/webhook/webhook

webhook-testwebhook


정리

n8n을 "워크플로우 자동화 도구"로만 보면 절반만 보는 거다.

n8n의 또 다른 얼굴:

  • Webhook으로 API 엔드포인트를 열 수 있다
  • 노드 단위로 인증을 걸 수 있다
  • 코드 없이 외부 API를 호출하고 응답을 가공할 수 있다
  • Docker로 셀프호스팅하면 데이터가 외부로 나가지 않는다

복잡한 API 서버를 만들 건 아니다. 근데 "이벤트 받아서 어딘가로 전달하고 응답 가공해서 돌려주는" 정도의 라우터가 필요하다면, n8n이 생각보다 좋은 선택이다.

Comments

잘못된 부분이 있을 수 있습니다 ! 자유롭게 댓글을 달아주세요 :)