Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure Functions - NodeJS - Response Body as a Stream

I'd like to return a file from Blob Storage when you hit a given Azure Function end-point. This file is binary data.

Per the Azure Storage Blob docs, the most relevant call appears to be the following since its the only one that doesn't require writing the file to an interim file: getBlobToStream

However this call gets the Blob and writes it to a stream.

Is there a way with Azure Functions to use a Stream as the value of res.body so that I can get the Blob Contents from storage and immediately write it to the response?

To add some code, trying to get something like this to work:

'use strict';
const   azure = require('azure-storage'),
        stream = require('stream');
const BLOB_CONTAINER = 'DeContainer';

module.exports = function(context){
    var file = context.bindingData.file;
    var blobService = azure.createBlobService();
    var outputStream = new stream.Writable();

    blobService.getBlobToStream(BLOB_CONTAINER, file, outputStream, function(error, serverBlob) {
        if(error) {
            FileNotFound(context);
        } else {
            context.res = {
                status: 200,
                headers: {

                },
                isRaw: true,
                body : outputStream
            };
            context.done();


        }
    });
}

function FileNotFound(context){
    context.res =  {
        status: 404,
        headers: {
            "Content-Type" : "application/json"
        },
        body : { "Message" : "No esta aqui!."}
    };
    context.done();
}
like image 933
Doug Avatar asked May 05 '17 16:05

Doug


People also ask

What is AzureWebJobsStorage?

AzureWebJobsStorage. The Azure Functions runtime uses this storage account connection string for normal operation. Some uses of this storage account include key management, timer trigger management, and Event Hubs checkpoints. The storage account must be a general-purpose one that supports blobs, queues, and tables.

Can Azure functions share code?

Create a folder named Shared at the root level of a Function App, and add shared code files to this folder. The WebJobs SDK (that Azure Functions are based on) watches for any code changes in the Shared folder and makes sure that the changes are picked up by the functions.


1 Answers

While @Matt Manson's answer is definitely correct based on the way I asked my question, the following code snippet might be more useful for someone who stumbles across this question.

While I can't send the Stream to the response body directly, I can use a custom stream which captures the data into a Uint8Array, and then sends that to the response body.

NOTE: If the file is REALLY big, this will use a lot of memory.

'use strict';
const   azure = require('azure-storage'),
        stream = require('stream');
const BLOB_CONTAINER = 'deContainer';

module.exports = function(context){
    var file = context.bindingData.file;
    var blobService = azure.createBlobService();
    var outputStream = new stream.Writable();
    outputStream.contents = new Uint8Array(0);//Initialize contents.

    //Override the write to store the value to our "contents"
    outputStream._write = function (chunk, encoding, done) {
        var curChunk = new Uint8Array(chunk);
        var tmp = new Uint8Array(this.contents.byteLength + curChunk.byteLength);
        tmp.set(this.contents, 0);
        tmp.set(curChunk, this.contents.byteLength);
        this.contents = tmp;
        done();
    };


    blobService.getBlobToStream(BLOB_CONTAINER, file, outputStream, function(error, serverBlob) {
        if(error) {
            FileNotFound(context);
        } else {
            context.res = {
                status: 200,
                headers: {

                },
                isRaw: true,
                body : outputStream.contents
            };
            context.done();
        }
    });//*/
}

function FileNotFound(context){
    context.res =  {
        status: 404,
        headers: {
            "Content-Type" : "application/json"
        },
        body : { "Message" : "No esta aqui!"}
    };
    context.done();
}
like image 113
Doug Avatar answered Sep 17 '22 20:09

Doug