Node.js Azure Functions でHTTPリクエストとレスポンスをストリーミングします

この記事では、Node.js 関数アプリでHTTPリクエストとレスポンスをストリーミングする方法について説明します。 ストリーミングの有効化、大規模データの処理、リアルタイムHTTPシナリオの処理方法を学びましょう。

Note

HTTPストリームはv4プログラミングモデルを必要とします。 v3を使っているなら、アップグレードのための 移行ガイド を参照してください。

Overview

HTTPストリーム機能により、大規模データの処理、OpenAIの応答のストリーミング、動的なコンテンツの提供、その他の主要なHTTPシナリオのサポートが容易になります。 これにより、Node.js 関数アプリの HTTP エンドポイントへの要求と HTTP エンドポイントからの応答をストリーミングできます。 アプリで、HTTP を経由してクライアントとサーバー間でリアルタイムの交換や対話を行う必要があるシナリオでは、HTTP ストリームを使用します。 また、HTTP ストリームを使用すると、HTTP を使用するときにアプリのパフォーマンスと信頼性を最大限に高めることができます。

前提条件

ストリームを有効にする

Azureおよびローカル プロジェクトで関数アプリで HTTP ストリームを有効にするには、次の手順を使用します。

  1. 大量のデータをストリーミングする場合は、Azureの FUNCTIONS_REQUEST_BODY_SIZE_LIMIT 設定を変更します。 デフォルトの最大ボディサイズは 104857600で、リクエストのサイズは約100MBに制限されます。

  2. ローカル開発の場合は、さらに、FUNCTIONS_REQUEST_BODY_SIZE_LIMITlocal.settings.json ファイルに追加します。

  3. アプリのメイン フィールドに含まれる任意のファイル内のアプリに次のコードを追加します。

const { app } = require("@azure/functions");

app.setup({ enableHttpStream: true });

Tip

ストリーミングの恩恵を最大限に引き出すには、 request.body を直接活用しましょう。 request.text()本体全体をバッファリングして文字列を返すような手法は、ストリーミングの目的を損なっています。

ストリームの例

以下の例は、HTTP POSTリクエストを通じてデータを受け取るHTTPトリガー関数を示しています。 関数はこのデータを指定された出力ファイルにストリーミングします:

const { app } = require("@azure/functions");
const fs = require("fs");
const path = require("path");

app.http("httpTriggerStreamRequest", {
  methods: ["POST"],
  handler: async (request, context) => {
    context.log("HTTP trigger function processed a request.");

    if (!request.body) {
      return {
        status: 400,
        body: "Request body is required"
      };
    }

    // Create a writable stream to a file
    const outputPath = path.join(__dirname, "streamed-output.txt");
    const writeStream = fs.createWriteStream(outputPath);

    try {
      // Stream the request body to the file
      const reader = request.body.getReader();
      let done = false;

      while (!done) {
        const { value, done: readerDone } = await reader.read();
        done = readerDone;
        
        if (value) {
          writeStream.write(value);
        }
      }

      writeStream.end();
      
      return {
        status: 200,
        body: "Data successfully streamed to file"
      };
    } catch (error) {
      context.log.error("Error streaming data:", error);
      return {
        status: 500,
        body: "Error processing stream"
      };
    }
  }
});

以下の例は、HTTPトリガー関数を示しており、ファイルの内容を受信するHTTP GETリクエストへの応答として配信します。

const { app } = require("@azure/functions");
const fs = require("fs");
const path = require("path");

app.http("httpTriggerStreamResponse", {
  methods: ["GET"],
  handler: async (request, context) => {
    context.log("HTTP trigger function processed a request.");

    const filePath = path.join(__dirname, "sample-data.txt");

    try {
      // Check if file exists
      if (!fs.existsSync(filePath)) {
        return {
          status: 404,
          body: "File not found"
        };
      }

      // Create a readable stream from the file
      const readStream = fs.createReadStream(filePath);
      
      return {
        status: 200,
        headers: {
          "Content-Type": "text/plain",
          "Transfer-Encoding": "chunked"
        },
        body: readStream
      };
    } catch (error) {
      context.log.error("Error streaming file:", error);
      return {
        status: 500,
        body: "Error streaming file"
      };
    }
  }
});

ストリームを使ったすぐに使えるサンプルアプリとして、GitHubのこの例をチェックしてみてください。