Blog Post

Apps on Azure Blog
3 MIN READ

Azure Functions: Support for HTTP Streams in Node.js is now in Preview

madhurabharadwaj's avatar
Feb 28, 2024
Azure Functions support for HTTP streams in Node.js is now in preview. With this feature, customers can now stream HTTP requests to and responses from their Functions Apps. 

 

Being one of the most requested features for Azure Functions, we’re confident that this release will unblock Node.js Functions customers and make scenarios like processing large data, streaming OpenAI responses, delivering dynamic content etc. possible. Customers can leverage this feature for use cases where real time exchange and interaction between client and server over HTTP connections is needed. We recommend using streams to get the best performance and reliability for your app. 

 

HTTP Streams in Node.js is supported only in the Azure Functions Node.js v4 programming model. Follow these instructions to try out HTTP Streams for your Node.js apps.

 

Prerequisites

 

  • Version 4 of the Node.js programming model. Learn more about the differences between v3 and v4 in the migration guide.
  • Version 4.3.0 or higher of the @azure/functions npm package.
  • If running in Azure, version 4.28 of the Azure Functions runtime.
  • If running locally, version 4.0.5530 of Azure Functions Core Tools.

 

Steps

 

  1. If you plan to stream large amounts of data, adjust the app setting FUNCTIONS_REQUEST_BODY_SIZE_LIMIT in Azure or in your local.settings.json file. The default value is 104857600, i.e., limiting your request to 100mb maximum.

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

    JavaScript

    const { app } = require('@azure/functions');
    
    app.setup({ enableHttpStream: true });


    TypeScript

    import { app } from '@azure/functions';
    
    app.setup({ enableHttpStream: true });
    

     

  3. That's it! The existing HttpRequest and HttpResponse types in programming model v4 already support many ways of handling the body, including as a stream. Use request.body to truly benefit from streams, but rest assured you can continue to use methods like request.text() which will always return the body as a string.

 

Example code

 

Below is an example of an HTTP triggered function that receives data via an HTTP POST request, and the function streams this data to a specified output file:
 
JavaScript
const { app } = require('@azure/functions');
const { createWriteStream } = require('fs');
const { Writable } = require('stream');

app.http('httpTriggerStreamRequest', {
    methods: ['POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        const writeStream = createWriteStream('<output file path>');
        await request.body.pipeTo(Writable.toWeb(writeStream));

        return { body: 'Done!' };
    },
});

TypeScript
import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';
import { createWriteStream } from 'fs';
import { Writable } from 'stream';

export async function httpTriggerStreamRequest(
    request: HttpRequest,
    context: InvocationContext
): Promise<HttpResponseInit> {
    const writeStream = createWriteStream('<output file path>');
    await request.body.pipeTo(Writable.toWeb(writeStream));

    return { body: 'Done!' };
}

app.http('httpTriggerStreamRequest', {
    methods: ['POST'],
    authLevel: 'anonymous',
    handler: httpTriggerStreamRequest,
});

 

Below is an example of an HTTP triggered function that streams a file's content as the response to incoming HTTP GET requests:

 

JavaScript

const { app } = require('@azure/functions');
const { createReadStream } = require('fs');

app.http('httpTriggerStreamResponse', {
    methods: ['GET'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        const body = createReadStream('<input file path>');

        return { body };
    },
});

 

TypeScript

import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';
import { createReadStream } from 'fs';

export async function httpTriggerStreamResponse(
    request: HttpRequest,
    context: InvocationContext
): Promise<HttpResponseInit> {
    const body = createReadStream('<input file path>');

    return { body };
}

app.http('httpTriggerStreamResponse', {
    methods: ['GET'],
    authLevel: 'anonymous',
    handler: httpTriggerStreamResponse,
});

 

Sample code

 

For a ready-to-run app with more detailed code, check out this GitHub repo.

 
Do try out this feature and share your valuable feedback with us on GitHub.
Updated Apr 10, 2024
Version 3.0