Edit

Stream HTTP requests and responses in Node.js Azure Functions

This article describes how to stream HTTP requests and responses in your Node.js function app. Learn how to enable streaming, process large data, and handle real-time HTTP scenarios.

Note

HTTP streams require the v4 programming model. If you're using v3, see the migration guide to upgrade.

Overview

The HTTP streams feature makes it easier to process large data, stream OpenAI responses, deliver dynamic content, and support other core HTTP scenarios. It lets you stream requests to and responses from HTTP endpoints in your Node.js function app. Use HTTP streams in scenarios where your app requires real-time exchange and interaction between client and server over HTTP. You can also use HTTP streams to get the best performance and reliability for your apps when using HTTP.

Prerequisites

Enable streams

Use these steps to enable HTTP streams in your function app in Azure and in your local projects:

  1. If you plan to stream large amounts of data, modify the FUNCTIONS_REQUEST_BODY_SIZE_LIMIT setting in Azure. The default maximum body size allowed is 104857600, which limits your requests to a size of about 100 MB.

  2. For local development, also add FUNCTIONS_REQUEST_BODY_SIZE_LIMIT to the local.settings.json file.

  3. Add the following code to your app in any file included by your main field.

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

app.setup({ enableHttpStream: true });

Tip

Use request.body directly to get the most benefit from streaming. Methods like request.text() buffer the entire body and return a string, which defeats the purpose of streaming.

Stream examples

The following example shows an HTTP triggered function that receives data through an HTTP POST request. The function streams this data to a specified output file:

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"
      };
    }
  }
});

The following example shows an HTTP triggered function that streams a file's content as the response to incoming HTTP GET requests:

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"
      };
    }
  }
});

For a ready-to-run sample app that uses streams, check out this example on GitHub.