🐕

n8n の Webhook が空レスポンスになる原因と、「When Last Node Finishes」で確実にデータを返す方法

に公開

Next.js やフロントエンドアプリから n8n に Webhook でデータを送り,
n8n 側で処理して JSON で応答したい。
シンプルに見えるが、実装してみると 「n8n では結果が見えているのに、クライアントには空レスポンスしか返らない」 という現象に遭遇しやすい。

Webhook のレスポンスが正しく返らない原因と、もっとも安定したレスポンス方式についてまとめる。

Webhook ノードのレスポンスは「Respond モード」で決まる

n8n の Webhook ノードには、HTTP レスポンスの返し方に関する設定がある。

代表的なモードは以下の3つ:

  • On Received

リクエストを受け取った瞬間にレスポンスを返す。
後続ノードの結果は返らない。

  • When Last Node Finishes

フローの最後に実行されたノードの結果をそのままレスポンスとして返す。

  • Using Respond to Webhook node

専用ノードを配置し、そこまでフローが到達した時点でレスポンスを返す。
制御が細かい反面、設定のズレでレスポンスが返らないトラブルが起きやすい。

空レスポンスが返る典型パターン

多くの場合、次のいずれかが原因:

Webhook ノードが On Received のまま

テスト URL と本番 URL を混在させている

Respond to Webhook ノードを置いたが Webhook と連動していない

Code ノードの返却形式が n8n の想定とズレている

n8n の UI 上ではデータが表示されるため気付きにくいが、
クライアント側から見ると “中身なし 200 OK” が返ってくるだけになる。

最も安定する構成:Webhook → Code →(When Last Node Finishes で返す)

レスポンスで迷子にならない方法はこれ。

  • フロー構造
    • Webhook
    • Code
      ※ Respond to Webhook ノードは使わない
  • Webhook の Respond
    When Last Node Finishes
  • Webhook の Response Data
    First Entry JSON

これで、最後の Code ノードの返り値がそのまま HTTP レスポンスになる。

Code ノードで返すべき形式

n8n の Code ノードは、配列の中に { json: データ } を入れて返すのがルール。

たとえば:

// Webhook 入力を取得(1件想定)
const input = $input.first().json;

// 任意の加工処理
const processed = {
  /* ここに処理したデータを入れる(データ構造は自由) */
};

// 配列として返すことで Webhook がレスポンスとして認識する
return [
  {
    json: processed,
  },
];

この “配列 + json キー” という形式を守れば、
データ内容がどんな構造でも確実に返る。

なぜ Respond to Webhook を使わない方が安定するのか?

Respond to Webhook は便利だが、以下の落とし穴がある:

  • Webhook ノード側の Respond モードが一致していないと動作しない
  • 複数の Respond to Webhook があると返却タイミングが曖昧になる
  • 分岐や並列フローで予期せぬタイミングで返ってしまう
  • テスト URL と本番 URL の挙動の差に気付きにくい

一方で Webhook → Code の 2 ノード構成は非常にシンプルで、
「最後のノード結果」=「レスポンス」という流れが明確。
API サーバのように使うなら、ほぼこの構成で足りる。

まとめ

  • Webhook の Respond は When Last Node Finishes がもっとも扱いやすい
  • Code ノードは 配列 + json キー の形式で返す
  • データの内容(フィールド名や構造)は完全に自由
  • Respond to Webhook は強力だが、レスポンス制御で迷いやすい
  • Webhook → Code の構成はシンプル・安定・トラブルが少ない

n8n を「API エンドポイントのように使いたい」場合、
この構成がもっとも実用的であり、バグも起きにくい。

Discussion